From 310562f52345d25b777e2e6c31c6f660ceb8aabe Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 03 2016 06:14:54 +0000 Subject: import bind-9.9.4-37.el7 --- diff --git a/.bind.metadata b/.bind.metadata index 5e29fe2..9cfc411 100644 --- a/.bind.metadata +++ b/.bind.metadata @@ -1,2 +1,3 @@ d7be390e6c2546f37a7280e1975e1cd134565f62 SOURCES/bind-9.9.4.tar.gz -3320c2bd77776079111603b7d266cc7ce7dcbd28 SOURCES/config-13.tar.bz2 +096a128b9272f1f2bb22ad0dfe62df24455f6f67 SOURCES/config-14.tar.bz2 +d3c4943f2f2aa1f7c51487af02ff3a52ca51a6d9 SOURCES/geoip-testing-data.tar.xz diff --git a/.gitignore b/.gitignore index 800c33e..4a26baf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ SOURCES/bind-9.9.4.tar.gz -SOURCES/config-13.tar.bz2 +SOURCES/config-14.tar.bz2 +SOURCES/geoip-testing-data.tar.xz diff --git a/SOURCES/bind-9.5-sdb.patch b/SOURCES/bind-9.5-sdb.patch index 99475e6..6af9818 100644 --- a/SOURCES/bind-9.5-sdb.patch +++ b/SOURCES/bind-9.5-sdb.patch @@ -1,6 +1,7 @@ -diff -up bind-9.9.4-P2/bin/Makefile.in.sdb bind-9.9.4-P2/bin/Makefile.in ---- bind-9.9.4-P2/bin/Makefile.in.sdb 2013-12-20 01:28:28.000000000 +0100 -+++ bind-9.9.4-P2/bin/Makefile.in 2014-07-22 10:29:23.940233449 +0200 +diff --git a/bin/Makefile.in b/bin/Makefile.in +index 187ec23..e6179e7 100644 +--- a/bin/Makefile.in ++++ b/bin/Makefile.in @@ -19,8 +19,8 @@ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @@ -12,64 +13,66 @@ diff -up bind-9.9.4-P2/bin/Makefile.in.sdb bind-9.9.4-P2/bin/Makefile.in TARGETS = @BIND9_MAKE_RULES@ -diff -up bind-9.9.4-P2/bin/named/Makefile.in.sdb bind-9.9.4-P2/bin/named/Makefile.in ---- bind-9.9.4-P2/bin/named/Makefile.in.sdb 2014-07-22 10:29:23.873233351 +0200 -+++ bind-9.9.4-P2/bin/named/Makefile.in 2014-07-22 10:30:43.247348398 +0200 -@@ -52,7 +52,7 @@ CINCLUDES = -I${srcdir}/include -I${srcd - ${ISCCFG_INCLUDES} ${ISCCC_INCLUDES} ${ISC_INCLUDES} \ - ${DLZDRIVER_INCLUDES} ${DBDRIVER_INCLUDES} @DST_OPENSSL_INC@ - --CDEFINES = @CONTRIB_DLZ@ @CRYPTO@ -+CDEFINES = @CRYPTO@ - - CWARNINGS = - -@@ -79,11 +79,11 @@ DEPLIBS = ${LWRESDEPLIBS} ${DNSDEPLIBS} +diff --git a/bin/named-sdb/Makefile.in b/bin/named-sdb/Makefile.in +index bc5be2a..71324d9 100644 +--- a/bin/named-sdb/Makefile.in ++++ b/bin/named-sdb/Makefile.in +@@ -34,10 +34,10 @@ top_srcdir = @top_srcdir@ + # + # Add database drivers here. + # +-DBDRIVER_OBJS = +-DBDRIVER_SRCS = ++DBDRIVER_OBJS = ldapdb.@O@ pgsqldb.@O@ dirdb.@O@ ++DBDRIVER_SRCS = ldapdb.c pgsqldb.c dirdb.c + DBDRIVER_INCLUDES = +-DBDRIVER_LIBS = ++DBDRIVER_LIBS = -lldap -llber -lpq - LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} \ - ${ISCCFGLIBS} ${ISCCCLIBS} ${ISCLIBS} \ -- ${DLZDRIVER_LIBS} ${DBDRIVER_LIBS} @LIBS@ -+ @LIBS@ + DLZ_DRIVER_DIR = ${top_srcdir}/contrib/dlz/drivers - NOSYMLIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} \ - ${ISCCFGLIBS} ${ISCCCLIBS} ${ISCNOSYMLIBS} \ -- ${DLZDRIVER_LIBS} ${DBDRIVER_LIBS} @LIBS@ -+ @LIBS@ +@@ -83,7 +83,7 @@ NOSYMLIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} \ SUBDIRS = unix -@@ -96,8 +96,7 @@ OBJS = builtin.@O@ client.@O@ config.@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} -+ lwdgnba.@O@ lwdgrbn.@O@ lwdnoop.@O@ lwsearch.@O@ - - UOBJS = unix/os.@O@ unix/dlz_dlopen_driver.@O@ +-TARGETS = named@EXEEXT@ lwresd@EXEEXT@ ++TARGETS = named-sdb@EXEEXT@ -@@ -110,8 +109,7 @@ SRCS = builtin.c client.c config.c cont - 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} -+ lwdgnba.c lwdgrbn.c lwdnoop.c lwsearch.c + GEOIPLINKOBJS = geoip.@O@ - MANPAGES = named.8 lwresd.8 named.conf.5 +@@ -146,7 +146,7 @@ config.@O@: config.c bind.keys.h + -DNS_SYSCONFDIR=\"${sysconfdir}\" \ + -c ${srcdir}/config.c -@@ -187,7 +185,5 @@ install:: named@EXEEXT@ lwresd@EXEEXT@ i - ${INSTALL_DATA} ${srcdir}/lwresd.8 ${DESTDIR}${mandir}/man8 - ${INSTALL_DATA} ${srcdir}/named.conf.5 ${DESTDIR}${mandir}/man5 +-named@EXEEXT@: ${OBJS} ${UOBJS} ${DEPLIBS} ++named-sdb@EXEEXT@: ${OBJS} ${UOBJS} ${DEPLIBS} + export MAKE_SYMTABLE="yes"; \ + export BASEOBJS="${OBJS} ${UOBJS}"; \ + ${FINALBUILDCMD} +@@ -177,15 +177,9 @@ statschannel.@O@: bind9.xsl.h bind9.ver3.xsl.h --@DLZ_DRIVER_RULES@ + installdirs: + $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir} +- $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man5 +- $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8 - - named-symtbl.@O@: named-symtbl.c - ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} -c named-symtbl.c -diff -up bind-9.9.4-P2/bin/named-sdb/main.c.sdb bind-9.9.4-P2/bin/named-sdb/main.c ---- bind-9.9.4-P2/bin/named-sdb/main.c.sdb 2014-07-22 10:29:23.919233417 +0200 -+++ bind-9.9.4-P2/bin/named-sdb/main.c 2014-07-22 10:29:23.940233449 +0200 -@@ -83,6 +83,9 @@ +-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 ++ ++install:: named-sdb@EXEEXT@ installdirs ++ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} named-sdb@EXEEXT@ ${DESTDIR}${sbindir} + + @DLZ_DRIVER_RULES@ + +diff --git a/bin/named-sdb/main.c b/bin/named-sdb/main.c +index a00687f..4fba625 100644 +--- a/bin/named-sdb/main.c ++++ b/bin/named-sdb/main.c +@@ -86,6 +86,9 @@ * Include header files for database drivers here. */ /* #include "xxdb.h" */ @@ -79,7 +82,7 @@ diff -up bind-9.9.4-P2/bin/named-sdb/main.c.sdb bind-9.9.4-P2/bin/named-sdb/main #ifdef CONTRIB_DLZ /* -@@ -814,6 +817,10 @@ setup(void) { +@@ -817,6 +820,10 @@ setup(void) { ns_main_earlyfatal("isc_app_start() failed: %s", isc_result_totext(result)); @@ -90,7 +93,7 @@ diff -up bind-9.9.4-P2/bin/named-sdb/main.c.sdb bind-9.9.4-P2/bin/named-sdb/main isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, "starting %s %s%s", ns_g_product, ns_g_version, saved_command_line); -@@ -926,6 +933,57 @@ setup(void) { +@@ -929,6 +936,57 @@ setup(void) { isc_result_totext(result)); #endif @@ -148,7 +151,7 @@ diff -up bind-9.9.4-P2/bin/named-sdb/main.c.sdb bind-9.9.4-P2/bin/named-sdb/main ns_server_create(ns_g_mctx, &ns_g_server); } -@@ -957,6 +1015,10 @@ cleanup(void) { +@@ -960,6 +1018,10 @@ cleanup(void) { dns_name_destroy(); @@ -159,63 +162,66 @@ diff -up bind-9.9.4-P2/bin/named-sdb/main.c.sdb bind-9.9.4-P2/bin/named-sdb/main isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, "exiting"); ns_log_shutdown(); -diff -up bind-9.9.4-P2/bin/named-sdb/Makefile.in.sdb bind-9.9.4-P2/bin/named-sdb/Makefile.in ---- bind-9.9.4-P2/bin/named-sdb/Makefile.in.sdb 2014-07-22 10:29:23.917233415 +0200 -+++ bind-9.9.4-P2/bin/named-sdb/Makefile.in 2014-07-22 10:29:23.941233449 +0200 -@@ -34,10 +34,10 @@ top_srcdir = @top_srcdir@ - # - # Add database drivers here. - # --DBDRIVER_OBJS = --DBDRIVER_SRCS = -+DBDRIVER_OBJS = ldapdb.@O@ pgsqldb.@O@ dirdb.@O@ -+DBDRIVER_SRCS = ldapdb.c pgsqldb.c dirdb.c - DBDRIVER_INCLUDES = --DBDRIVER_LIBS = -+DBDRIVER_LIBS = -lldap -llber -lpq +diff --git a/bin/named/Makefile.in b/bin/named/Makefile.in +index bc5be2a..3c69c9b 100644 +--- a/bin/named/Makefile.in ++++ b/bin/named/Makefile.in +@@ -51,7 +51,7 @@ CINCLUDES = -I${srcdir}/include -I${srcdir}/unix/include -I. \ + ${ISCCFG_INCLUDES} ${ISCCC_INCLUDES} ${ISC_INCLUDES} \ + ${DLZDRIVER_INCLUDES} ${DBDRIVER_INCLUDES} @DST_OPENSSL_INC@ - DLZ_DRIVER_DIR = ${top_srcdir}/contrib/dlz/drivers +-CDEFINES = @CONTRIB_DLZ@ @CRYPTO@ ++CDEFINES = @CRYPTO@ -@@ -87,7 +87,7 @@ NOSYMLIBS = ${LWRESLIBS} ${DNSLIBS} ${BI + CWARNINGS = - SUBDIRS = unix +@@ -75,11 +75,11 @@ DEPLIBS = ${LWRESDEPLIBS} ${DNSDEPLIBS} ${BIND9DEPLIBS} \ --TARGETS = named@EXEEXT@ lwresd@EXEEXT@ -+TARGETS = named-sdb@EXEEXT@ + LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} \ + ${ISCCFGLIBS} ${ISCCCLIBS} ${ISCLIBS} \ +- ${DLZDRIVER_LIBS} ${DBDRIVER_LIBS} @LIBS@ ++ @LIBS@ - OBJS = builtin.@O@ client.@O@ config.@O@ control.@O@ \ - controlconf.@O@ interfacemgr.@O@ \ -@@ -146,7 +146,7 @@ config.@O@: config.c bind.keys.h - -DNS_SYSCONFDIR=\"${sysconfdir}\" \ - -c ${srcdir}/config.c + NOSYMLIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} \ + ${ISCCFGLIBS} ${ISCCCLIBS} ${ISCNOSYMLIBS} \ +- ${DLZDRIVER_LIBS} ${DBDRIVER_LIBS} @LIBS@ ++ @LIBS@ --named@EXEEXT@: ${OBJS} ${UOBJS} ${DEPLIBS} -+named-sdb@EXEEXT@: ${OBJS} ${UOBJS} ${DEPLIBS} - export MAKE_SYMTABLE="yes"; \ - export BASEOBJS="${OBJS} ${UOBJS}"; \ - ${FINALBUILDCMD} -@@ -177,15 +177,9 @@ statschannel.@O@: bind9.xsl.h bind9.ver3 + SUBDIRS = unix - installdirs: - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir} -- $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man5 -- $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8 +@@ -94,8 +94,7 @@ 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@ \ +- ${DLZDRIVER_OBJS} ${DBDRIVER_OBJS} ++ lwdgnba.@O@ lwdgrbn.@O@ lwdnoop.@O@ lwsearch.@O@ --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 -+install:: named-sdb@EXEEXT@ installdirs -+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} named-sdb@EXEEXT@ ${DESTDIR}${sbindir} + UOBJS = unix/os.@O@ unix/dlz_dlopen_driver.@O@ - @DLZ_DRIVER_RULES@ +@@ -110,8 +109,7 @@ 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 \ +- ${DLZDRIVER_SRCS} ${DBDRIVER_SRCS} ++ lwdgnba.c lwdgrbn.c lwdnoop.c lwsearch.c -diff -up bind-9.9.4-P2/configure.in.sdb bind-9.9.4-P2/configure.in ---- bind-9.9.4-P2/configure.in.sdb 2014-07-22 10:29:23.909233403 +0200 -+++ bind-9.9.4-P2/configure.in 2014-07-22 10:29:23.942233450 +0200 -@@ -3900,12 +3900,15 @@ AC_CONFIG_FILES([ + MANPAGES = named.8 lwresd.8 named.conf.5 + +@@ -187,7 +185,5 @@ install:: named@EXEEXT@ lwresd@EXEEXT@ installdirs + ${INSTALL_DATA} ${srcdir}/lwresd.8 ${DESTDIR}${mandir}/man8 + ${INSTALL_DATA} ${srcdir}/named.conf.5 ${DESTDIR}${mandir}/man5 + +-@DLZ_DRIVER_RULES@ +- + named-symtbl.@O@: named-symtbl.c + ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} -c named-symtbl.c +diff --git a/configure.in b/configure.in +index 9bb9a2a..d72093f 100644 +--- a/configure.in ++++ b/configure.in +@@ -4018,12 +4018,15 @@ AC_CONFIG_FILES([ bin/named-pkcs11/Makefile bin/named-pkcs11/unix/Makefile bin/named/unix/Makefile diff --git a/SOURCES/bind-9.9-dist-native-pkcs11.patch b/SOURCES/bind-9.9-dist-native-pkcs11.patch index f12312b..9e6f846 100644 --- a/SOURCES/bind-9.9-dist-native-pkcs11.patch +++ b/SOURCES/bind-9.9-dist-native-pkcs11.patch @@ -1,26 +1,3 @@ -From 28f61b8a12da4a8dd10dccaefe8e50fc8605b87e Mon Sep 17 00:00:00 2001 -From: Tomas Hozza -Date: Mon, 22 Sep 2014 16:44:29 +0200 -Subject: [PATCH] Distributing native PKCS#11 BIND and utils - -Signed-off-by: Tomas Hozza ---- - bin/Makefile.in | 2 +- - bin/dnssec-pkcs11/Makefile.in | 40 +++++++++++------------ - bin/dnssec/Makefile.in | 2 +- - bin/named-pkcs11/Makefile.in | 40 +++++++++-------------- - bin/named/Makefile.in | 2 +- - bin/pkcs11/Makefile.in | 6 ++-- - configure.in | 68 +++++++++++++++++++++++++++++++-------- - lib/Makefile.in | 2 +- - lib/dns-pkcs11/Makefile.in | 24 +++++++------- - lib/export/Makefile.in | 2 +- - lib/export/dns-pkcs11/Makefile.in | 26 +++++++-------- - lib/export/isc-pkcs11/Makefile.in | 18 +++++------ - lib/isc-pkcs11/Makefile.in | 24 +++++++------- - make/includes.in | 10 ++++++ - 14 files changed, 154 insertions(+), 112 deletions(-) - diff --git a/bin/Makefile.in b/bin/Makefile.in index 87ca5b2..187ec23 100644 --- a/bin/Makefile.in @@ -157,7 +134,7 @@ index 64e1846..cfb5628 100644 CWARNINGS = diff --git a/bin/named-pkcs11/Makefile.in b/bin/named-pkcs11/Makefile.in -index cd65777..be791ca 100644 +index 3a54437..32c5242 100644 --- a/bin/named-pkcs11/Makefile.in +++ b/bin/named-pkcs11/Makefile.in @@ -47,26 +47,26 @@ DLZDRIVER_INCLUDES = @DLZ_DRIVER_INCLUDES@ @@ -211,9 +188,9 @@ index cd65777..be791ca 100644 -TARGETS = named@EXEEXT@ lwresd@EXEEXT@ +TARGETS = named-pkcs11@EXEEXT@ - OBJS = builtin.@O@ client.@O@ config.@O@ control.@O@ \ - controlconf.@O@ interfacemgr.@O@ \ -@@ -92,8 +92,7 @@ OBJS = builtin.@O@ client.@O@ config.@O@ control.@O@ \ + GEOIPLINKOBJS = geoip.@O@ + +@@ -94,8 +94,7 @@ 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@ \ @@ -223,7 +200,7 @@ index cd65777..be791ca 100644 UOBJS = unix/os.@O@ unix/dlz_dlopen_driver.@O@ -@@ -106,8 +105,7 @@ SRCS = builtin.c client.c config.c control.c \ +@@ -110,8 +109,7 @@ 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 \ @@ -233,7 +210,7 @@ index cd65777..be791ca 100644 MANPAGES = named.8 lwresd.8 named.conf.5 -@@ -142,7 +140,7 @@ config.@O@: config.c bind.keys.h +@@ -146,7 +144,7 @@ config.@O@: config.c bind.keys.h -DNS_SYSCONFDIR=\"${sysconfdir}\" \ -c ${srcdir}/config.c @@ -242,7 +219,7 @@ index cd65777..be791ca 100644 export MAKE_SYMTABLE="yes"; \ export BASEOBJS="${OBJS} ${UOBJS}"; \ ${FINALBUILDCMD} -@@ -173,15 +171,9 @@ statschannel.@O@: bind9.xsl.h bind9.ver3.xsl.h +@@ -177,15 +175,9 @@ statschannel.@O@: bind9.xsl.h bind9.ver3.xsl.h installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir} @@ -262,7 +239,7 @@ index cd65777..be791ca 100644 @DLZ_DRIVER_RULES@ diff --git a/bin/named/Makefile.in b/bin/named/Makefile.in -index cd65777..a5d46b6 100644 +index 3a54437..bc5be2a 100644 --- a/bin/named/Makefile.in +++ b/bin/named/Makefile.in @@ -51,7 +51,7 @@ CINCLUDES = -I${srcdir}/include -I${srcdir}/unix/include -I. \ @@ -296,7 +273,7 @@ index 15d3fb5..32cc753 100644 DEPLIBS = ${ISCDEPLIBS} diff --git a/configure.in b/configure.in -index d4dc6fd..2fbcfcb 100644 +index 5b56172..9bb9a2a 100644 --- a/configure.in +++ b/configure.in @@ -656,10 +656,10 @@ AC_ARG_WITH(pkcs11, @@ -374,7 +351,7 @@ index d4dc6fd..2fbcfcb 100644 AC_SUBST(PKCS11_ECDSA) AC_SUBST(PKCS11_GOST) AC_SUBST(PKCS11_TEST) -@@ -1435,12 +1437,13 @@ AC_SUBST(USE_GSSAPI) +@@ -1528,12 +1530,13 @@ AC_SUBST(USE_GSSAPI) AC_SUBST(DST_GSSAPI_INC) AC_SUBST(DNS_GSSAPI_LIBS) DNS_CRYPTO_LIBS="$DNS_GSSAPI_LIBS $DNS_CRYPTO_LIBS" @@ -389,7 +366,7 @@ index d4dc6fd..2fbcfcb 100644 # # was --with-randomdev specified? -@@ -3918,7 +3921,10 @@ AC_CONFIG_FILES([ +@@ -4010,7 +4013,10 @@ AC_CONFIG_FILES([ bin/confgen/unix/Makefile bin/dig/Makefile bin/dnssec/Makefile @@ -400,7 +377,7 @@ index d4dc6fd..2fbcfcb 100644 bin/named/unix/Makefile bin/nsupdate/Makefile bin/pkcs11/Makefile -@@ -3998,11 +4004,19 @@ AC_CONFIG_FILES([ +@@ -4091,11 +4097,19 @@ AC_CONFIG_FILES([ lib/dns/include/dns/Makefile lib/dns/include/dst/Makefile lib/dns/tests/Makefile @@ -420,7 +397,7 @@ index d4dc6fd..2fbcfcb 100644 lib/export/irs/Makefile lib/export/irs/include/Makefile lib/export/irs/include/irs/Makefile -@@ -4016,6 +4030,16 @@ AC_CONFIG_FILES([ +@@ -4109,6 +4123,16 @@ AC_CONFIG_FILES([ lib/export/isc/unix/Makefile lib/export/isc/unix/include/Makefile lib/export/isc/unix/include/isc/Makefile @@ -437,7 +414,7 @@ index d4dc6fd..2fbcfcb 100644 lib/export/isccfg/Makefile lib/export/isccfg/include/Makefile lib/export/isccfg/include/isccfg/Makefile -@@ -4044,6 +4068,24 @@ AC_CONFIG_FILES([ +@@ -4137,6 +4161,24 @@ AC_CONFIG_FILES([ lib/isc/unix/include/Makefile lib/isc/unix/include/isc/Makefile lib/isc/unix/include/pkcs11/Makefile @@ -476,7 +453,7 @@ index 8dc1d38..8e48d5e 100644 @BIND9_MAKE_RULES@ diff --git a/lib/dns-pkcs11/Makefile.in b/lib/dns-pkcs11/Makefile.in -index 41fac95..7d88424 100644 +index 0cc82f1..cb830db 100644 --- a/lib/dns-pkcs11/Makefile.in +++ b/lib/dns-pkcs11/Makefile.in @@ -27,16 +27,16 @@ top_srcdir = @top_srcdir@ @@ -500,7 +477,7 @@ index 41fac95..7d88424 100644 LIBS = @LIBS@ -@@ -132,27 +132,27 @@ dynamic_db.@O@: dynamic_db.c +@@ -136,27 +136,27 @@ dynamic_db.@O@: dynamic_db.c -DDYNDB_LIBDIR=\"@libdir@/bind/\" \ -c ${srcdir}/dynamic_db.c @@ -535,7 +512,7 @@ index 41fac95..7d88424 100644 rm -f gen code.h include/dns/enumtype.h include/dns/enumclass.h rm -f include/dns/rdatastruct.h -@@ -182,7 +182,7 @@ code.h: gen +@@ -186,7 +186,7 @@ code.h: gen ./gen -s ${srcdir} > code.h gen: gen.c @@ -558,7 +535,7 @@ index 1fd7216..a8a1342 100644 @BIND9_MAKE_RULES@ diff --git a/lib/export/dns-pkcs11/Makefile.in b/lib/export/dns-pkcs11/Makefile.in -index e10bf59..669509f 100644 +index 54e4e39..71c6b25 100644 --- a/lib/export/dns-pkcs11/Makefile.in +++ b/lib/export/dns-pkcs11/Makefile.in @@ -15,7 +15,7 @@ @@ -592,7 +569,7 @@ index e10bf59..669509f 100644 LIBS = @LIBS@ -@@ -116,29 +116,29 @@ version.@O@: ${srcdir}/version.c +@@ -114,29 +114,29 @@ version.@O@: ${srcdir}/version.c -DLIBAGE=${LIBAGE} \ -c ${srcdir}/version.c @@ -630,7 +607,7 @@ index e10bf59..669509f 100644 rm -f include/dns/rdatastruct.h diff --git a/lib/export/isc-pkcs11/Makefile.in b/lib/export/isc-pkcs11/Makefile.in -index e12dffb..926e000 100644 +index a5f8bd0..7655a9b 100644 --- a/lib/export/isc-pkcs11/Makefile.in +++ b/lib/export/isc-pkcs11/Makefile.in @@ -15,7 +15,7 @@ @@ -688,7 +665,7 @@ index e12dffb..926e000 100644 - rm -f libisc-export.@A@ libisc-export.la timestamp + rm -f libisc-pkcs11-export.@A@ libisc-pkcs11-export.la timestamp diff --git a/lib/isc-pkcs11/Makefile.in b/lib/isc-pkcs11/Makefile.in -index 801ab35..d326786 100644 +index df62ec9..d9f0107 100644 --- a/lib/isc-pkcs11/Makefile.in +++ b/lib/isc-pkcs11/Makefile.in @@ -31,8 +31,8 @@ CINCLUDES = -I${srcdir}/unix/include \ @@ -766,6 +743,3 @@ index f2f1b3f..639477c 100644 + +DNS_PKCS11_INCLUDES = @BIND9_DNS_BUILDINCLUDE@ \ + -I${top_srcdir}/lib/dns-pkcs11/include --- -1.9.3 - diff --git a/SOURCES/bind99-automatic-interface-scanning-rh1294506.patch b/SOURCES/bind99-automatic-interface-scanning-rh1294506.patch new file mode 100644 index 0000000..0aec0c5 --- /dev/null +++ b/SOURCES/bind99-automatic-interface-scanning-rh1294506.patch @@ -0,0 +1,685 @@ +From 5013230b31da1d94ce5682e5c5c38011da744971 Mon Sep 17 00:00:00 2001 +From: Tomas Hozza +Date: Wed, 11 May 2016 15:17:55 +0200 +Subject: [PATCH] Added support for automatic interface scan when new address + is assigned to any interface + +Signed-off-by: Tomas Hozza +--- + bin/named/config.c | 1 + + bin/named/control.c | 3 + + bin/named/include/named/control.h | 1 + + bin/named/include/named/server.h | 8 +++ + bin/named/interfacemgr.c | 144 ++++++++++++++++++++++++++++++++++++++ + bin/named/named.conf.docbook | 1 + + bin/named/server.c | 31 +++++++- + bin/named/statschannel.c | 5 ++ + bin/rndc/rndc.c | 1 + + bin/rndc/rndc.docbook | 12 ++++ + config.h.in | 12 ++++ + configure.in | 5 +- + doc/arm/Bv9ARM-book.xml | 22 +++++- + lib/isc/include/isc/socket.h | 10 ++- + lib/isc/unix/socket.c | 59 ++++++++++++++++ + lib/isccfg/namedconf.c | 1 + + 16 files changed, 310 insertions(+), 6 deletions(-) + +diff --git a/bin/named/config.c b/bin/named/config.c +index f6d0263..b43c0fc 100644 +--- a/bin/named/config.c ++++ b/bin/named/config.c +@@ -52,6 +52,7 @@ + /*% default configuration */ + static char defaultconf[] = "\ + options {\n\ ++ automatic-interface-scan yes;\n\ + # blackhole {none;};\n" + #ifndef WIN32 + " coresize default;\n\ +diff --git a/bin/named/control.c b/bin/named/control.c +index 06eadce..86fa691 100644 +--- a/bin/named/control.c ++++ b/bin/named/control.c +@@ -185,6 +185,9 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) { + command_compare(command, NS_COMMAND_THAW)) { + result = ns_server_freeze(ns_g_server, ISC_FALSE, command, + 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_SYNC)) { + result = ns_server_sync(ns_g_server, command, text); + } else if (command_compare(command, NS_COMMAND_RECURSING)) { +diff --git a/bin/named/include/named/control.h b/bin/named/include/named/control.h +index d730a83..52ed583 100644 +--- a/bin/named/include/named/control.h ++++ b/bin/named/include/named/control.h +@@ -59,6 +59,7 @@ + #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" +diff --git a/bin/named/include/named/server.h b/bin/named/include/named/server.h +index ff0bfd3..83622f4 100644 +--- a/bin/named/include/named/server.h ++++ b/bin/named/include/named/server.h +@@ -37,6 +37,7 @@ + #define NS_EVENTCLASS ISC_EVENTCLASS(0x4E43) + #define NS_EVENT_RELOAD (NS_EVENTCLASS + 0) + #define NS_EVENT_CLIENTCONTROL (NS_EVENTCLASS + 1) ++#define NS_EVENT_IFSCAN (NS_EVENTCLASS + 2) + + /*% + * Name server state. Better here than in lots of separate global variables. +@@ -114,6 +115,7 @@ struct ns_server { + dns_name_t *session_keyname; + unsigned int session_keyalg; + isc_uint16_t session_keybits; ++ isc_boolean_t interface_auto; + }; + + #define NS_SERVER_MAGIC ISC_MAGIC('S','V','E','R') +@@ -201,6 +203,12 @@ ns_server_reloadwanted(ns_server_t *server); + */ + + void ++ns_server_scan_interfaces(ns_server_t *server); ++/*%< ++ * Trigger a interface scan. ++ */ ++ ++void + ns_server_flushonshutdown(ns_server_t *server, isc_boolean_t flush); + /*%< + * Inform the server that the zones should be flushed to disk on shutdown. +diff --git a/bin/named/interfacemgr.c b/bin/named/interfacemgr.c +index 4f6b0f3..a9aa4a4 100644 +--- a/bin/named/interfacemgr.c ++++ b/bin/named/interfacemgr.c +@@ -33,6 +33,28 @@ + #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 + + #define IFMGR_MAGIC ISC_MAGIC('I', 'F', 'M', 'G') + #define NS_INTERFACEMGR_VALID(t) ISC_MAGIC_VALID(t, IFMGR_MAGIC) +@@ -55,6 +77,11 @@ struct ns_interfacemgr { + 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 +@@ -63,6 +90,71 @@ 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; ++ ++ 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); ++ isc_task_detach(&mgr->task); ++ isc_socket_detach(&mgr->route); ++ ns_interfacemgr_detach(&mgr); ++ isc_event_free(&event); ++ return; ++ } ++#endif ++ ++ switch (rtm->MSGTYPE) { ++ case RTM_NEWADDR: ++ case RTM_DELADDR: ++ if (ns_g_server->interface_auto) ++ ns_server_scan_interfaces(ns_g_server); ++ break; ++ default: ++ break; ++ } ++ ++ /* ++ * 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) ++ ns_interfacemgr_detach(&mgr); ++ isc_event_free(&event); ++} ++#endif ++ + isc_result_t + ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, + isc_socketmgr_t *socketmgr, +@@ -112,11 +204,52 @@ ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, + 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) { ++ result = isc_task_create(taskmgr, 0, &mgr->task); ++ if (result != ISC_R_SUCCESS) ++ goto cleanup_route; ++ } ++ 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) ++ ns_interfacemgr_detach(&mgr); ++ } ++#endif + return (ISC_R_SUCCESS); + ++#ifdef USE_ROUTE_SOCKET ++ cleanup_route: ++ if (mgr->route != NULL) ++ isc_socket_detach(&mgr->route); ++ cleanup_aclenv: ++ dns_aclenv_destroy(&mgr->aclenv); ++#endif + cleanup_listenon: + ns_listenlist_detach(&mgr->listenon4); + ns_listenlist_detach(&mgr->listenon6); +@@ -128,6 +261,13 @@ ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, + 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); +@@ -179,6 +319,10 @@ ns_interfacemgr_shutdown(ns_interfacemgr_t *mgr) { + * consider all interfaces "old". + */ + mgr->generation++; ++#ifdef USE_ROUTE_SOCKET ++ if (mgr->route != NULL) ++ isc_socket_cancel(mgr->route, mgr->task, ISC_SOCKCANCEL_RECV); ++#endif + purge_old_interfaces(mgr); + } + +diff --git a/bin/named/named.conf.docbook b/bin/named/named.conf.docbook +index 8c23e52..a8cd31e 100644 +--- a/bin/named/named.conf.docbook ++++ b/bin/named/named.conf.docbook +@@ -373,6 +373,7 @@ options { + zero-no-soa-ttl boolean; + zero-no-soa-ttl-cache boolean; + dnssec-secure-to-insecure boolean; ++ automatic-interface-scan boolean; + deny-answer-addresses { + address_match_list + } except-from { namelist } ; +diff --git a/bin/named/server.c b/bin/named/server.c +index 24b31c3..942bab6 100644 +--- a/bin/named/server.c ++++ b/bin/named/server.c +@@ -4485,8 +4485,9 @@ adjust_interfaces(ns_server_t *server, isc_mem_t *mctx) { + } + + /* +- * This event callback is invoked to do periodic network +- * interface scanning. ++ * 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) { +@@ -4494,7 +4495,14 @@ interface_timer_tick(isc_task_t *task, isc_event_t *event) { + ns_server_t *server = (ns_server_t *) event->ev_arg; + INSIST(task == server->task); + UNUSED(task); ++ ++ if (event->ev_type == NS_EVENT_IFSCAN) ++ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, ++ NS_LOGMODULE_SERVER, ISC_LOG_DEBUG(1), ++ "automatic interface rescan"); ++ + isc_event_free(&event); ++ + /* + * XXX should scan interfaces unlocked and get exclusive access + * only to replace ACLs. +@@ -5419,6 +5427,14 @@ load_configuration(const char *filename, ns_server_t *server, + 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; +@@ -6637,6 +6653,17 @@ ns_server_reloadwanted(ns_server_t *server) { + UNLOCK(&server->reload_event_lock); + } + ++void ++ns_server_scan_interfaces(ns_server_t *server) { ++ isc_event_t *event; ++ ++ event = isc_event_allocate(ns_g_mctx, server, NS_EVENT_IFSCAN, ++ interface_timer_tick, server, ++ sizeof(isc_event_t)); ++ if (event != NULL) ++ isc_task_send(server->task, &event); ++} ++ + static char * + next_token(char **stringp, const char *delim) { + char *res; +diff --git a/bin/named/statschannel.c b/bin/named/statschannel.c +index 37e98a8..b985f62 100644 +--- a/bin/named/statschannel.c ++++ b/bin/named/statschannel.c +@@ -341,6 +341,7 @@ init_desc(void) { + 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", +@@ -351,6 +352,8 @@ init_desc(void) { + "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"); +@@ -358,6 +361,7 @@ init_desc(void) { + 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", +@@ -424,6 +428,7 @@ init_desc(void) { + "UnixRecvErr"); + SET_SOCKSTATDESC(fdwatchrecvfail, "FDwatch recv errors", + "FDwatchRecvErr"); ++ SET_SOCKSTATDESC(rawrecvfail, "Raw recv errors", "RawRecvErr"); + INSIST(i == isc_sockstatscounter_max); + + /* Initialize DNSSEC statistics */ +diff --git a/bin/rndc/rndc.c b/bin/rndc/rndc.c +index 9a007e2..be198b1 100644 +--- a/bin/rndc/rndc.c ++++ b/bin/rndc/rndc.c +@@ -160,6 +160,7 @@ command is one of the following:\n\ + Add zone to given view. Requires new-zone-file option.\n\ + delzone [\"file\"] zone [class [view]]\n\ + Removes zone from given view. Requires new-zone-file option.\n\ ++ scan Scan available network interfaces for changes.\n\ + signing -list zone [class [view]]\n\ + List the private records showing the state of DNSSEC\n\ + signing in the given zone.\n\ +diff --git a/bin/rndc/rndc.docbook b/bin/rndc/rndc.docbook +index 1789aaa..5b37b7f 100644 +--- a/bin/rndc/rndc.docbook ++++ b/bin/rndc/rndc.docbook +@@ -330,6 +330,18 @@ + + + ++ scan ++ ++ ++ Scan the list of available network interfaces ++ for changes, without performing a full ++ reconfig or waiting for the ++ interface-interval timer. ++ ++ ++ ++ ++ + sync -clean zone class view + + +diff --git a/config.h.in b/config.h.in +index 6ed8381..3515f69 100644 +--- a/config.h.in ++++ b/config.h.in +@@ -280,6 +280,12 @@ int sigwait(const unsigned int *set, int *sig); + /* Define to 1 if you have the header file. */ + #undef HAVE_LINUX_CAPABILITY_H + ++/* Define to 1 if you have the header file. */ ++#undef HAVE_LINUX_NETLINK_H ++ ++/* Define to 1 if you have the header file. */ ++#undef HAVE_LINUX_RTNETLINK_H ++ + /* Define to 1 if you have the header file. */ + #undef HAVE_LINUX_TYPES_H + +@@ -295,6 +301,9 @@ int sigwait(const unsigned int *set, int *sig); + /* Define to 1 if you have the header file. */ + #undef HAVE_NET_IF6_H + ++/* Define to 1 if you have the header file. */ ++#undef HAVE_NET_ROUTE_H ++ + /* Define if your OpenSSL version supports ECDSA. */ + #undef HAVE_OPENSSL_ECDSA + +@@ -358,6 +367,9 @@ int sigwait(const unsigned int *set, int *sig); + /* Define to 1 if you have the header file. */ + #undef HAVE_SYS_SELECT_H + ++/* Define to 1 if you have the header file. */ ++#undef HAVE_SYS_SOCKET_H ++ + /* Define to 1 if you have the header file. */ + #undef HAVE_SYS_SOCKIO_H + +diff --git a/configure.in b/configure.in +index d72093f..38e626d 100644 +--- a/configure.in ++++ b/configure.in +@@ -375,11 +375,14 @@ fi + + AC_HEADER_STDC + +-AC_CHECK_HEADERS(fcntl.h regex.h sys/time.h unistd.h sys/sockio.h sys/select.h sys/param.h sys/sysctl.h net/if6.h,,, ++AC_CHECK_HEADERS(fcntl.h regex.h sys/time.h unistd.h sys/sockio.h sys/select.h sys/param.h sys/sysctl.h net/if6.h sys/socket.h net/route.h linux/netlink.h linux/rtnetlink.h,,, + [$ac_includes_default + #ifdef HAVE_SYS_PARAM_H + # include + #endif ++#ifdef HAVE_SYS_SOCKET_H ++# include ++#endif + ]) + + AC_C_CONST +diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml +index 92c7b72..4c47d92 100644 +--- a/doc/arm/Bv9ARM-book.xml ++++ b/doc/arm/Bv9ARM-book.xml +@@ -4964,7 +4964,9 @@ badresp:1,adberr:0,findfail:0,valfail:0] + policy given | disabled | passthru | nxdomain | nodata | cname domain + recursive-only yes_or_no max-policy-ttl number ; + } recursive-only yes_or_no max-policy-ttl number +- break-dnssec yes_or_no min-ns-dots number ; ++ break-dnssec yes_or_no min-ns-dots number ++ automatic-interface-scan yes_or_no ++ ; + }; + + +@@ -5726,6 +5728,23 @@ options { + + + ++ automatic-interface-scan ++ ++ ++ If yes and supported by the OS, ++ automatically rescan network interfaces when the interface ++ addresses are added or removed. The default is ++ yes. ++ ++ ++ Currently the OS needs to support routing sockets for ++ automatic-interface-scan to be ++ supported. ++ ++ ++ ++ ++ + allow-new-zones + + +@@ -10494,6 +10513,7 @@ zone zone_name class allow-query-on { address_match_list }; + allow-transfer { address_match_list }; + allow-update-forwarding { address_match_list }; ++ automatic-interface-scan { yes_or_no }; + dnssec-update-mode ( maintain | no-resign ); + update-check-ksk yes_or_no; + dnssec-dnskey-kskonly yes_or_no; +diff --git a/lib/isc/include/isc/socket.h b/lib/isc/include/isc/socket.h +index c5a753a..1cd90bb 100644 +--- a/lib/isc/include/isc/socket.h ++++ b/lib/isc/include/isc/socket.h +@@ -150,7 +150,12 @@ enum { + isc_sockstatscounter_unixrecvfail = 50, + isc_sockstatscounter_fdwatchrecvfail = 51, + +- isc_sockstatscounter_max = 52 ++ isc_sockstatscounter_rawopen = 52, ++ isc_sockstatscounter_rawopenfail = 53, ++ isc_sockstatscounter_rawclose = 54, ++ isc_sockstatscounter_rawrecvfail = 55, ++ ++ isc_sockstatscounter_max = 56 + }; + + /*** +@@ -221,7 +226,8 @@ typedef enum { + isc_sockettype_udp = 1, + isc_sockettype_tcp = 2, + isc_sockettype_unix = 3, +- isc_sockettype_fdwatch = 4 ++ isc_sockettype_fdwatch = 4, ++ isc_sockettype_raw = 5 + } isc_sockettype_t; + + /*@{*/ +diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c +index 82d0d16..cbc506b 100644 +--- a/lib/isc/unix/socket.c ++++ b/lib/isc/unix/socket.c +@@ -28,6 +28,11 @@ + #include + #include + ++#if defined(HAVE_LINUX_NETLINK_H) && defined(HAVE_LINUX_RTNETLINK_H) ++#include ++#include ++#endif ++ + #include + #include + #include +@@ -708,6 +713,18 @@ static const isc_statscounter_t fdwatchstatsindex[] = { + isc_sockstatscounter_fdwatchsendfail, + isc_sockstatscounter_fdwatchrecvfail + }; ++static const isc_statscounter_t rawstatsindex[] = { ++ isc_sockstatscounter_rawopen, ++ isc_sockstatscounter_rawopenfail, ++ isc_sockstatscounter_rawclose, ++ -1, ++ -1, ++ -1, ++ -1, ++ -1, ++ -1, ++ isc_sockstatscounter_rawrecvfail, ++}; + + #if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL) || \ + defined(USE_WATCHER_THREAD) +@@ -1744,6 +1761,7 @@ doio_recv(isc__socket_t *sock, isc_socketevent_t *dev) { + return (DOIO_EOF); + break; + case isc_sockettype_udp: ++ case isc_sockettype_raw: + break; + case isc_sockettype_fdwatch: + default: +@@ -2306,6 +2324,44 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock, + case isc_sockettype_unix: + sock->fd = socket(sock->pf, SOCK_STREAM, 0); + break; ++ case isc_sockettype_raw: ++ errno = EPFNOSUPPORT; ++ /* ++ * PF_ROUTE is a alias for PF_NETLINK on linux. ++ */ ++#if defined(PF_ROUTE) ++ if (sock->fd == -1 && sock->pf == PF_ROUTE) { ++#ifdef NETLINK_ROUTE ++ sock->fd = socket(sock->pf, SOCK_RAW, ++ NETLINK_ROUTE); ++#else ++ sock->fd = socket(sock->pf, SOCK_RAW, 0); ++#endif ++ if (sock->fd != -1) { ++#ifdef NETLINK_ROUTE ++ struct sockaddr_nl sa; ++ int n; ++ ++ /* ++ * Do an implicit bind. ++ */ ++ memset(&sa, 0, sizeof(sa)); ++ sa.nl_family = AF_NETLINK; ++ sa.nl_groups = RTMGRP_IPV4_IFADDR | ++ RTMGRP_IPV6_IFADDR; ++ n = bind(sock->fd, ++ (struct sockaddr *) &sa, ++ sizeof(sa)); ++ if (n < 0) { ++ close(sock->fd); ++ sock->fd = -1; ++ } ++#endif ++ sock->bound = 1; ++ } ++ } ++ #endif ++ break; + case isc_sockettype_fdwatch: + /* + * We should not be called for isc_sockettype_fdwatch +@@ -2602,6 +2658,9 @@ socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, + case isc_sockettype_unix: + sock->statsindex = unixstatsindex; + break; ++ case isc_sockettype_raw: ++ sock->statsindex = rawstatsindex; ++ break; + default: + INSIST(0); + } +diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c +index f5ff8e3..f49ff70 100644 +--- a/lib/isccfg/namedconf.c ++++ b/lib/isccfg/namedconf.c +@@ -931,6 +931,7 @@ bindkeys_clauses[] = { + */ + static cfg_clausedef_t + options_clauses[] = { ++ { "automatic-interface-scan", &cfg_type_boolean, 0 }, + { "avoid-v4-udp-ports", &cfg_type_bracketed_portlist, 0 }, + { "avoid-v6-udp-ports", &cfg_type_bracketed_portlist, 0 }, + { "bindkeys-file", &cfg_type_qstring, 0 }, +-- +2.5.5 + diff --git a/SOURCES/bind99-rh1220594-geoip.patch b/SOURCES/bind99-rh1220594-geoip.patch new file mode 100644 index 0000000..a6c3d08 --- /dev/null +++ b/SOURCES/bind99-rh1220594-geoip.patch @@ -0,0 +1,5536 @@ +From 7af058d28da052c9fb03083f6c4de1f9af564d08 Mon Sep 17 00:00:00 2001 +From: Tomas Hozza +Date: Wed, 13 Apr 2016 09:57:31 +0200 +Subject: [PATCH] Added support for GeoIP + +Signed-off-by: Tomas Hozza +--- + bin/named/Makefile.in | 8 +- + bin/named/geoip.c | 148 +++++ + bin/named/include/named/geoip.h | 31 + + bin/named/include/named/globals.h | 5 + + bin/named/interfacemgr.c | 3 + + bin/named/server.c | 38 +- + bin/tests/system/Makefile.in | 3 +- + bin/tests/system/conf.sh.in | 2 +- + bin/tests/system/geoip/Makefile.in | 55 ++ + bin/tests/system/geoip/clean.sh | 23 + + bin/tests/system/geoip/data/GeoIP.csv | 7 + + bin/tests/system/geoip/data/GeoIPASNum.csv | 7 + + bin/tests/system/geoip/data/GeoIPASNumv6.csv | 7 + + bin/tests/system/geoip/data/GeoIPCity.csv | 7 + + bin/tests/system/geoip/data/GeoIPCityv6.csv | 7 + + bin/tests/system/geoip/data/GeoIPDomain.csv | 7 + + bin/tests/system/geoip/data/GeoIPISP.csv | 7 + + bin/tests/system/geoip/data/GeoIPNetSpeed.csv | 7 + + bin/tests/system/geoip/data/GeoIPOrg.csv | 7 + + bin/tests/system/geoip/data/GeoIPRegion.csv | 7 + + bin/tests/system/geoip/data/GeoIPv6.csv | 7 + + bin/tests/system/geoip/data/README | 29 + + bin/tests/system/geoip/geoip.c | 31 + + bin/tests/system/geoip/ns2/example.db.in | 24 + + bin/tests/system/geoip/ns2/named1.conf | 104 ++++ + bin/tests/system/geoip/ns2/named10.conf | 104 ++++ + bin/tests/system/geoip/ns2/named11.conf | 104 ++++ + bin/tests/system/geoip/ns2/named12.conf | 80 +++ + bin/tests/system/geoip/ns2/named13.conf | 45 ++ + bin/tests/system/geoip/ns2/named14.conf | 112 ++++ + bin/tests/system/geoip/ns2/named15.conf | 55 ++ + bin/tests/system/geoip/ns2/named2.conf | 104 ++++ + bin/tests/system/geoip/ns2/named3.conf | 104 ++++ + bin/tests/system/geoip/ns2/named4.conf | 96 +++ + bin/tests/system/geoip/ns2/named5.conf | 104 ++++ + bin/tests/system/geoip/ns2/named6.conf | 104 ++++ + bin/tests/system/geoip/ns2/named7.conf | 104 ++++ + bin/tests/system/geoip/ns2/named8.conf | 104 ++++ + bin/tests/system/geoip/ns2/named9.conf | 104 ++++ + bin/tests/system/geoip/options.conf | 42 ++ + bin/tests/system/geoip/prereq.sh | 23 + + bin/tests/system/geoip/setup.sh | 27 + + bin/tests/system/geoip/tests.sh | 328 +++++++++++ + config.h.in | 9 + + configure.in | 94 +++ + doc/arm/Bv9ARM-book.xml | 72 +++ + lib/dns/Makefile.in | 8 +- + lib/dns/acl.c | 23 +- + lib/dns/geoip.c | 820 ++++++++++++++++++++++++++ + lib/dns/include/dns/Makefile.in | 2 +- + lib/dns/include/dns/acl.h | 24 +- + lib/dns/include/dns/geoip.h | 119 ++++ + lib/dns/tests/Makefile.in | 9 +- + lib/dns/tests/geoip_test.c | 694 ++++++++++++++++++++++ + lib/export/dns/Makefile.in | 18 +- + lib/isccfg/aclconf.c | 361 +++++++++++- + lib/isccfg/include/isccfg/aclconf.h | 6 + + lib/isccfg/namedconf.c | 129 +++- + 58 files changed, 4673 insertions(+), 40 deletions(-) + create mode 100644 bin/named/geoip.c + create mode 100644 bin/named/include/named/geoip.h + create mode 100644 bin/tests/system/geoip/Makefile.in + create mode 100644 bin/tests/system/geoip/clean.sh + create mode 100644 bin/tests/system/geoip/data/GeoIP.csv + create mode 100644 bin/tests/system/geoip/data/GeoIPASNum.csv + create mode 100644 bin/tests/system/geoip/data/GeoIPASNumv6.csv + create mode 100644 bin/tests/system/geoip/data/GeoIPCity.csv + create mode 100644 bin/tests/system/geoip/data/GeoIPCityv6.csv + create mode 100644 bin/tests/system/geoip/data/GeoIPDomain.csv + create mode 100644 bin/tests/system/geoip/data/GeoIPISP.csv + create mode 100644 bin/tests/system/geoip/data/GeoIPNetSpeed.csv + create mode 100644 bin/tests/system/geoip/data/GeoIPOrg.csv + create mode 100644 bin/tests/system/geoip/data/GeoIPRegion.csv + create mode 100644 bin/tests/system/geoip/data/GeoIPv6.csv + create mode 100644 bin/tests/system/geoip/data/README + create mode 100644 bin/tests/system/geoip/geoip.c + create mode 100644 bin/tests/system/geoip/ns2/example.db.in + create mode 100644 bin/tests/system/geoip/ns2/named1.conf + create mode 100644 bin/tests/system/geoip/ns2/named10.conf + create mode 100644 bin/tests/system/geoip/ns2/named11.conf + create mode 100644 bin/tests/system/geoip/ns2/named12.conf + create mode 100644 bin/tests/system/geoip/ns2/named13.conf + create mode 100644 bin/tests/system/geoip/ns2/named14.conf + create mode 100644 bin/tests/system/geoip/ns2/named15.conf + create mode 100644 bin/tests/system/geoip/ns2/named2.conf + create mode 100644 bin/tests/system/geoip/ns2/named3.conf + create mode 100644 bin/tests/system/geoip/ns2/named4.conf + create mode 100644 bin/tests/system/geoip/ns2/named5.conf + create mode 100644 bin/tests/system/geoip/ns2/named6.conf + create mode 100644 bin/tests/system/geoip/ns2/named7.conf + create mode 100644 bin/tests/system/geoip/ns2/named8.conf + create mode 100644 bin/tests/system/geoip/ns2/named9.conf + create mode 100644 bin/tests/system/geoip/options.conf + create mode 100644 bin/tests/system/geoip/prereq.sh + create mode 100644 bin/tests/system/geoip/setup.sh + create mode 100644 bin/tests/system/geoip/tests.sh + create mode 100644 lib/dns/geoip.c + create mode 100644 lib/dns/include/dns/geoip.h + create mode 100644 lib/dns/tests/geoip_test.c + +diff --git a/bin/named/Makefile.in b/bin/named/Makefile.in +index cd65777..3a54437 100644 +--- a/bin/named/Makefile.in ++++ b/bin/named/Makefile.in +@@ -85,8 +85,10 @@ SUBDIRS = unix + + TARGETS = named@EXEEXT@ lwresd@EXEEXT@ + ++GEOIPLINKOBJS = geoip.@O@ ++ + OBJS = builtin.@O@ client.@O@ config.@O@ control.@O@ \ +- controlconf.@O@ interfacemgr.@O@ \ ++ controlconf.@O@ @GEOIPLINKOBJS@ 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@ \ +@@ -99,8 +101,10 @@ UOBJS = unix/os.@O@ unix/dlz_dlopen_driver.@O@ + + SYMOBJS = symtbl.@O@ + ++GEOIPLINKSRCS = geoip.c ++ + SRCS = builtin.c client.c config.c control.c \ +- controlconf.c interfacemgr.c \ ++ controlconf.c @GEOIPLINKSRCS@ interfacemgr.c \ + listenlist.c log.c logconf.c main.c notify.c \ + query.c server.c sortlist.c statschannel.c symtbl.c symtbl-empty.c \ + tkeyconf.c tsigconf.c update.c xfrout.c \ +diff --git a/bin/named/geoip.c b/bin/named/geoip.c +new file mode 100644 +index 0000000..c8f0c62 +--- /dev/null ++++ b/bin/named/geoip.c +@@ -0,0 +1,148 @@ ++/* ++ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") ++ * ++ * 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 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 ++ ++#ifdef HAVE_GEOIP ++static dns_geoip_databases_t geoip_table = { ++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ++}; ++ ++static void ++init_geoip_db(GeoIP **dbp, GeoIPDBTypes edition, GeoIPDBTypes fallback, ++ GeoIPOptions method, const char *name) ++{ ++ char *info; ++ GeoIP *db; ++ ++ REQUIRE(dbp != NULL); ++ ++ db = *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); ++ ++ *dbp = db; ++ return; ++ fail: ++ if (fallback != 0) ++ init_geoip_db(dbp, fallback, 0, method, name); ++ ++} ++#endif /* HAVE_GEOIP */ ++ ++void ++ns_geoip_init(void) { ++#ifndef HAVE_GEOIP ++ return; ++#else ++ GeoIP_cleanup(); ++ if (ns_g_geoip == NULL) ++ ns_g_geoip = &geoip_table; ++#endif ++} ++ ++void ++ns_geoip_load(char *dir) { ++#ifndef HAVE_GEOIP ++ ++ UNUSED(dir); ++ ++ return; ++#else ++ 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"); ++#endif /* HAVE_GEOIP */ ++} +diff --git a/bin/named/include/named/geoip.h b/bin/named/include/named/geoip.h +new file mode 100644 +index 0000000..e1a66a7 +--- /dev/null ++++ b/bin/named/include/named/geoip.h +@@ -0,0 +1,31 @@ ++/* ++ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") ++ * ++ * 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 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 _GEOIP_H ++#define _GEOIP_H ++ ++#ifdef HAVE_GEOIP ++#include ++#include ++#endif /* HAVE_GEOIP */ ++ ++void ns_geoip_init(void); ++void ns_geoip_load(char *dir); ++ ++#ifdef HAVE_GEOIP ++extern dns_geoip_databases_t *ns_g_geoip; ++#endif /* HAVE_GEOIP */ ++#endif +diff --git a/bin/named/include/named/globals.h b/bin/named/include/named/globals.h +index aad462d..412b3a7 100644 +--- a/bin/named/include/named/globals.h ++++ b/bin/named/include/named/globals.h +@@ -29,6 +29,7 @@ + #include + #include + ++#include + #include + + #include +@@ -160,6 +161,10 @@ EXTERN isc_boolean_t ns_g_nosoa INIT(ISC_FALSE); + EXTERN isc_boolean_t ns_g_noaa INIT(ISC_FALSE); + EXTERN isc_boolean_t ns_g_nonearest INIT(ISC_FALSE); + ++#ifdef HAVE_GEOIP ++EXTERN dns_geoip_databases_t *ns_g_geoip INIT(NULL); ++#endif ++ + #undef EXTERN + #undef INIT + +diff --git a/bin/named/interfacemgr.c b/bin/named/interfacemgr.c +index 9206ebb..4f6b0f3 100644 +--- a/bin/named/interfacemgr.c ++++ b/bin/named/interfacemgr.c +@@ -108,6 +108,9 @@ ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, + result = dns_aclenv_init(mctx, &mgr->aclenv); + if (result != ISC_R_SUCCESS) + goto cleanup_listenon; ++#ifdef HAVE_GEOIP ++ mgr->aclenv.geoip = ns_g_geoip; ++#endif + + mgr->references = 1; + mgr->magic = IFMGR_MAGIC; +diff --git a/bin/named/server.c b/bin/named/server.c +index 5e94660..24b31c3 100644 +--- a/bin/named/server.c ++++ b/bin/named/server.c +@@ -98,6 +98,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -113,6 +114,9 @@ + #include + #include + #endif ++#ifdef HAVE_GEOIP ++#include ++#endif /* HAVE_GEOIP */ + + #ifndef PATH_MAX + #define PATH_MAX 1024 +@@ -3841,6 +3845,10 @@ create_view(const cfg_obj_t *vconfig, dns_viewlist_t *viewlist, + if (result != ISC_R_SUCCESS) + 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); +@@ -5164,6 +5172,24 @@ load_configuration(const char *filename, ns_server_t *server, + } + isc__socketmgr_setreserved(ns_g_socketmgr, reserved); + ++#ifdef HAVE_GEOIP ++ /* ++ * 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); ++ } else ++ ns_geoip_load(NULL); ++ ns_g_aclconfctx->geoip = ns_g_geoip; ++#endif /* HAVE_GEOIP */ ++ + /* + * Configure various server options. + */ +@@ -6176,6 +6202,10 @@ shutdown_server(isc_task_t *task, isc_event_t *event) { + if (server->blackholeacl != NULL) + dns_acl_detach(&server->blackholeacl); + ++#ifdef HAVE_GEOIP ++ dns_geoip_shutdown(); ++#endif ++ + dns_db_detach(&server->in_roothints); + + isc_task_endexclusive(server->task); +@@ -6197,7 +6227,6 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) { + 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); +@@ -6205,9 +6234,16 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) { + 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); + ++#ifdef HAVE_GEOIP ++ /* 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; +diff --git a/bin/tests/system/Makefile.in b/bin/tests/system/Makefile.in +index 1479824..5e3c63e 100644 +--- a/bin/tests/system/Makefile.in ++++ b/bin/tests/system/Makefile.in +@@ -21,8 +21,7 @@ top_srcdir = @top_srcdir@ + + @BIND9_MAKE_INCLUDES@ + +-SUBDIRS = filter-aaaa lwresd rpz rrl \ +- rsabigexponent tkey tsiggss ++SUBDIRS = filter-aaaa geoip lwresd rpz rrl rsabigexponent tkey tsiggss + TARGETS = + + @BIND9_MAKE_RULES@ +diff --git a/bin/tests/system/conf.sh.in b/bin/tests/system/conf.sh.in +index c40e8f1..c3beac1 100644 +--- a/bin/tests/system/conf.sh.in ++++ b/bin/tests/system/conf.sh.in +@@ -65,7 +65,7 @@ SUBDIRS="acl additional allow_query addzone autosign builtin + lwresd masterfile masterformat metadata notify nsupdate pending + @PKCS11_TEST@ redirect resolver rndc rpz rrl rrsetorder rsabigexponent + smartsign sortlist spf staticstub stub tkey tsig tsiggss unknown +- upforwd verify views wildcard xfer xferquota zero zonechecks" ++ upforwd verify views wildcard xfer xferquota zero zonechecks geoip filter-aaaa" + + # PERL will be an empty string if no perl interpreter was found. + PERL=@PERL@ +diff --git a/bin/tests/system/geoip/Makefile.in b/bin/tests/system/geoip/Makefile.in +new file mode 100644 +index 0000000..ab48003 +--- /dev/null ++++ b/bin/tests/system/geoip/Makefile.in +@@ -0,0 +1,55 @@ ++# Copyright (C) 2010-2012 Internet Systems Consortium, Inc. ("ISC") ++# ++# 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 DISCLAIMS ALL WARRANTIES WITH ++# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ++# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, ++# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ++# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ++# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ++# PERFORMANCE OF THIS SOFTWARE. ++ ++# $Id: Makefile.in,v 1.4 2011/07/28 23:47:58 tbox Exp $ ++ ++srcdir = @srcdir@ ++VPATH = @srcdir@ ++top_srcdir = @top_srcdir@ ++ ++@BIND9_VERSION@ ++ ++@BIND9_MAKE_INCLUDES@ ++ ++CINCLUDES = ${ISC_INCLUDES} ++ ++CDEFINES = ++CWARNINGS = ++ ++DNSLIBS = ++ISCLIBS = . ++ ++DNSDEPLIBS = ++ISCDEPLIBS = ++ ++DEPLIBS = ++ ++LIBS = @LIBS@ ++ ++TARGETS = geoip@EXEEXT@ ++ ++FILTEROBJS = geoip.@O@ ++ ++SRCS = geoip.c ++ ++@BIND9_MAKE_RULES@ ++ ++all: geoip@EXEEXT@ ++ ++geoip@EXEEXT@: ${FILTEROBJS} ++ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ ${FILTEROBJS} ${LIBS} ++ ++clean distclean:: ++ rm -f ${TARGETS} ++ +diff --git a/bin/tests/system/geoip/clean.sh b/bin/tests/system/geoip/clean.sh +new file mode 100644 +index 0000000..b04ca2d +--- /dev/null ++++ b/bin/tests/system/geoip/clean.sh +@@ -0,0 +1,23 @@ ++#!/bin/sh ++# ++# Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") ++# ++# 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 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. ++ ++rm -f ns2/named.conf ++rm -f ns2/example*.db ++rm -f dig.out.* rndc.out.* ++rm -f data2/*dat ++[ -d data2 ] && rmdir data2 ++rm -f ns?/named.run ++rm -f ns?/named.memstats +diff --git a/bin/tests/system/geoip/data/GeoIP.csv b/bin/tests/system/geoip/data/GeoIP.csv +new file mode 100644 +index 0000000..f158a5b +--- /dev/null ++++ b/bin/tests/system/geoip/data/GeoIP.csv +@@ -0,0 +1,7 @@ ++10.53.0.1/32 AU ++10.53.0.2/32 US ++10.53.0.3/32 GB ++10.53.0.4/32 CA ++10.53.0.5/32 CL ++10.53.0.6/32 DE ++10.53.0.7/32 EH +diff --git a/bin/tests/system/geoip/data/GeoIPASNum.csv b/bin/tests/system/geoip/data/GeoIPASNum.csv +new file mode 100644 +index 0000000..774edd1 +--- /dev/null ++++ b/bin/tests/system/geoip/data/GeoIPASNum.csv +@@ -0,0 +1,7 @@ ++10.53.0.1/32 AS100001 One Systems, Inc. ++10.53.0.2/32 AS100002 Two Technology Ltd. ++10.53.0.3/32 AS100003 Three Network Labs ++10.53.0.4/32 AS100004 Four University ++10.53.0.5/32 AS100005 Five Telecom ++10.53.0.6/32 AS100006 Six Company ++10.53.0.7/32 AS100007 Seven Communications +diff --git a/bin/tests/system/geoip/data/GeoIPASNumv6.csv b/bin/tests/system/geoip/data/GeoIPASNumv6.csv +new file mode 100644 +index 0000000..4074289 +--- /dev/null ++++ b/bin/tests/system/geoip/data/GeoIPASNumv6.csv +@@ -0,0 +1,7 @@ ++fd92:7065:b8e:ffff::1/128,AS100001 One Systems, Inc. ++fd92:7065:b8e:ffff::2/128,AS100002 Two Technology Ltd. ++fd92:7065:b8e:ffff::3/128,AS100003 Three Network Labs ++fd92:7065:b8e:ffff::4/128,AS100004 Four University ++fd92:7065:b8e:ffff::5/128,AS100005 Five Telecom ++fd92:7065:b8e:ffff::6/128,AS100006 Six Company ++fd92:7065:b8e:ffff::7/128,AS100007 Seven Communications +diff --git a/bin/tests/system/geoip/data/GeoIPCity.csv b/bin/tests/system/geoip/data/GeoIPCity.csv +new file mode 100644 +index 0000000..14900d5 +--- /dev/null ++++ b/bin/tests/system/geoip/data/GeoIPCity.csv +@@ -0,0 +1,7 @@ ++10.53.0.1/32,US,CA,"Redwood City",94063,37.4914,-122.2110,807,650 ++10.53.0.2/32,US,CA,"Santa Cruz",95060,37.0448,-122.1021,828,831 ++10.53.0.3/32,US,OK,"Oklahoma City",73120,35.5798,-97.5731,650,405 ++10.53.0.4/32,US,VA,Ashland,23005,37.7563,-77.4888,556,804 ++10.53.0.5/32,US,GA,Atlanta,30345,33.8477,-84.2814,524,404 ++10.53.0.6/32,US,CO,Morrison,80465,39.6081,-105.2072,751,303 ++10.53.0.7/32,US,AK,Ketchikan,99901,55.6153,-131.5848,747,907 +diff --git a/bin/tests/system/geoip/data/GeoIPCityv6.csv b/bin/tests/system/geoip/data/GeoIPCityv6.csv +new file mode 100644 +index 0000000..5f09e62 +--- /dev/null ++++ b/bin/tests/system/geoip/data/GeoIPCityv6.csv +@@ -0,0 +1,7 @@ ++"fd92:7065:b8e:ffff::1","fd92:7065:b8e:ffff::1","US","CA","Redwood City","94063",37.4914,-122.2110,807,650 ++"fd92:7065:b8e:ffff::2","fd92:7065:b8e:ffff::2","US","CA","Santa Cruz","95060",37.0448,-122.1021,828,831 ++"fd92:7065:b8e:ffff::3","fd92:7065:b8e:ffff::3","US","OK","Oklahoma City","73120",35.5798,-97.5731,650,405 ++"fd92:7065:b8e:ffff::4","fd92:7065:b8e:ffff::4","DE","07","Lotte","",52.2833,7.9167,0,0 ++"fd92:7065:b8e:ffff::5","fd92:7065:b8e:ffff::5","US","GA","Atlanta","30345",33.8477,-84.2814,524,404 ++"fd92:7065:b8e:ffff::6","fd92:7065:b8e:ffff::6","US","CO","Morrison","80465",39.6081,-105.2072,751,303 ++"fd92:7065:b8e:ffff::7","fd92:7065:b8e:ffff::7","US","AK","Ketchikan","99901",55.6153,-131.5848,747,907 +diff --git a/bin/tests/system/geoip/data/GeoIPDomain.csv b/bin/tests/system/geoip/data/GeoIPDomain.csv +new file mode 100644 +index 0000000..8611d65 +--- /dev/null ++++ b/bin/tests/system/geoip/data/GeoIPDomain.csv +@@ -0,0 +1,7 @@ ++10.53.0.1/32 one.de ++10.53.0.2/32 two.com ++10.53.0.3/32 three.com ++10.53.0.4/32 four.com ++10.53.0.5/32 five.es ++10.53.0.6/32 six.it ++10.53.0.7/32 seven.org +diff --git a/bin/tests/system/geoip/data/GeoIPISP.csv b/bin/tests/system/geoip/data/GeoIPISP.csv +new file mode 100644 +index 0000000..3d5b4fa +--- /dev/null ++++ b/bin/tests/system/geoip/data/GeoIPISP.csv +@@ -0,0 +1,7 @@ ++10.53.0.1/32 One Systems, Inc. ++10.53.0.2/32 Two Technology Ltd. ++10.53.0.3/32 Three Network Labs ++10.53.0.4/32 Four University ++10.53.0.5/32 Five Telecom ++10.53.0.6/32 Six Company ++10.53.0.7/32 Seven Communications +diff --git a/bin/tests/system/geoip/data/GeoIPNetSpeed.csv b/bin/tests/system/geoip/data/GeoIPNetSpeed.csv +new file mode 100644 +index 0000000..4ede137 +--- /dev/null ++++ b/bin/tests/system/geoip/data/GeoIPNetSpeed.csv +@@ -0,0 +1,7 @@ ++10.53.0.1/32 0 ++10.53.0.2/32 1 ++10.53.0.3/32 2 ++10.53.0.4/32 3 ++10.53.0.5/32 0 ++10.53.0.6/32 1 ++10.53.0.7/32 2 +diff --git a/bin/tests/system/geoip/data/GeoIPOrg.csv b/bin/tests/system/geoip/data/GeoIPOrg.csv +new file mode 100644 +index 0000000..3d5b4fa +--- /dev/null ++++ b/bin/tests/system/geoip/data/GeoIPOrg.csv +@@ -0,0 +1,7 @@ ++10.53.0.1/32 One Systems, Inc. ++10.53.0.2/32 Two Technology Ltd. ++10.53.0.3/32 Three Network Labs ++10.53.0.4/32 Four University ++10.53.0.5/32 Five Telecom ++10.53.0.6/32 Six Company ++10.53.0.7/32 Seven Communications +diff --git a/bin/tests/system/geoip/data/GeoIPRegion.csv b/bin/tests/system/geoip/data/GeoIPRegion.csv +new file mode 100644 +index 0000000..0bcd872 +--- /dev/null ++++ b/bin/tests/system/geoip/data/GeoIPRegion.csv +@@ -0,0 +1,7 @@ ++10.53.0.1/32 US CA ++10.53.0.2/32 CA BC ++10.53.0.3/32 US OK ++10.53.0.4/32 AU ++10.53.0.5/32 US CO ++10.53.0.6/32 CA ON ++10.53.0.7/32 NL +diff --git a/bin/tests/system/geoip/data/GeoIPv6.csv b/bin/tests/system/geoip/data/GeoIPv6.csv +new file mode 100644 +index 0000000..919bf86 +--- /dev/null ++++ b/bin/tests/system/geoip/data/GeoIPv6.csv +@@ -0,0 +1,7 @@ ++"fd92:7065:b8e:ffff::1/128",AU ++"fd92:7065:b8e:ffff::2/128",US ++"fd92:7065:b8e:ffff::3/128",GB ++"fd92:7065:b8e:ffff::4/128",CA ++"fd92:7065:b8e:ffff::5/128",CL ++"fd92:7065:b8e:ffff::6/128",DE ++"fd92:7065:b8e:ffff::7/128",EH +diff --git a/bin/tests/system/geoip/data/README b/bin/tests/system/geoip/data/README +new file mode 100644 +index 0000000..0711cde +--- /dev/null ++++ b/bin/tests/system/geoip/data/README +@@ -0,0 +1,29 @@ ++The data data files in this directory are sample GeoIP databases, ++generated from the corresponding CSV files. Thanks to MaxMind, Inc. ++for assistance with producing these files. ++ ++Unless otherwise noted, the databases only support IPv4: ++ ++GeoIP.dat: Country (IPv4) ++GeoIPv6.dat: Country (IPv6) ++GeoIPCity.dat: City (IPv4) ++GeoIPCityv6.dat: City (IPv6) ++GeoIPRegion.dat: Region ++GeoIPISP.dat: ISP ++GeoIPOrg.dat: Organization ++GeoIPDoain.dat: Domain Name ++GeoIPASNum.dat: AS Number ++GeoIPNetSpeed.dat: Net Speed ++ ++GeoIP.dat can also be generated using the open source 'geoip-csv-to-dat' ++utility: ++ ++$ geoip-csv-to-dat -i "BIND9 geoip test data v1" -o GeoIP.dat << EOF ++"10.53.0.1","10.53.0.1","171245569","171245569","AU","Australia" ++"10.53.0.2","10.53.0.2","171245570","171245570","US","United States" ++"10.53.0.3","10.53.0.3","171245571","171245571","GB","United Kingdom" ++"10.53.0.4","10.53.0.4","171245572","171245572","CA","Canada" ++"10.53.0.5","10.53.0.5","171245573","171245573","CL","Chile" ++"10.53.0.6","10.53.0.6","171245574","171245574","DE","Germany" ++"10.53.0.7","10.53.0.7","171245575","171245575","EH","Western Sahara" ++EOF +diff --git a/bin/tests/system/geoip/geoip.c b/bin/tests/system/geoip/geoip.c +new file mode 100644 +index 0000000..e0dadad +--- /dev/null ++++ b/bin/tests/system/geoip/geoip.c +@@ -0,0 +1,31 @@ ++/* ++ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") ++ * ++ * 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 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 ++ ++int ++main(int argc, char **argv) { ++ ++ UNUSED(argc); ++ UNUSED(argv); ++ ++#ifdef HAVE_GEOIP ++ return (0); ++#else ++ return (1); ++#endif ++} +diff --git a/bin/tests/system/geoip/ns2/example.db.in b/bin/tests/system/geoip/ns2/example.db.in +new file mode 100644 +index 0000000..52a233b +--- /dev/null ++++ b/bin/tests/system/geoip/ns2/example.db.in +@@ -0,0 +1,24 @@ ++; Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC") ++; ++; 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 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. ++ ++$TTL 300 ; 5 minutes ++@ IN SOA mname1. . ( ++ 2000042407 ; serial ++ 20 ; refresh (20 seconds) ++ 20 ; retry (20 seconds) ++ 1814400 ; expire (3 weeks) ++ 3600 ; minimum (1 hour) ++ ) ++ NS ns2 ++ns2 A 10.53.0.2 +diff --git a/bin/tests/system/geoip/ns2/named1.conf b/bin/tests/system/geoip/ns2/named1.conf +new file mode 100644 +index 0000000..66aca6f +--- /dev/null ++++ b/bin/tests/system/geoip/ns2/named1.conf +@@ -0,0 +1,104 @@ ++/* ++ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") ++ * ++ * 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 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. ++ */ ++ ++// NS2 ++ ++controls { /* empty */ }; ++ ++options { ++ query-source address 10.53.0.2; ++ notify-source 10.53.0.2; ++ transfer-source 10.53.0.2; ++ port 5300; ++ pid-file "named.pid"; ++ listen-on { 10.53.0.2; }; ++ listen-on-v6 { none; }; ++ recursion no; ++ geoip-directory "../data"; ++}; ++ ++key rndc_key { ++ secret "1234abcd8765"; ++ algorithm hmac-md5; ++}; ++ ++controls { ++ inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; }; ++}; ++ ++view one { ++ match-clients { geoip db country country AU; }; ++ zone "example" { ++ type master; ++ file "example1.db"; ++ }; ++}; ++ ++view two { ++ match-clients { geoip db country country US; }; ++ zone "example" { ++ type master; ++ file "example2.db"; ++ }; ++}; ++ ++view three { ++ match-clients { geoip db country country GB; }; ++ zone "example" { ++ type master; ++ file "example3.db"; ++ }; ++}; ++ ++view four { ++ match-clients { geoip db country country CA; }; ++ zone "example" { ++ type master; ++ file "example4.db"; ++ }; ++}; ++ ++view five { ++ match-clients { geoip db country country CL; }; ++ zone "example" { ++ type master; ++ file "example5.db"; ++ }; ++}; ++ ++view six { ++ match-clients { geoip db country country DE; }; ++ zone "example" { ++ type master; ++ file "example6.db"; ++ }; ++}; ++ ++view seven { ++ match-clients { geoip db country country EH; }; ++ zone "example" { ++ type master; ++ file "example7.db"; ++ }; ++}; ++ ++view none { ++ match-clients { any; }; ++ zone "example" { ++ type master; ++ file "example.db.in"; ++ }; ++}; +diff --git a/bin/tests/system/geoip/ns2/named10.conf b/bin/tests/system/geoip/ns2/named10.conf +new file mode 100644 +index 0000000..2dd52ae +--- /dev/null ++++ b/bin/tests/system/geoip/ns2/named10.conf +@@ -0,0 +1,104 @@ ++/* ++ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") ++ * ++ * 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 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. ++ */ ++ ++// NS2 ++ ++controls { /* empty */ }; ++ ++options { ++ query-source address 10.53.0.2; ++ notify-source 10.53.0.2; ++ transfer-source 10.53.0.2; ++ port 5300; ++ pid-file "named.pid"; ++ listen-on { 10.53.0.2; }; ++ listen-on-v6 { none; }; ++ recursion no; ++ geoip-directory "../data"; ++}; ++ ++key rndc_key { ++ secret "1234abcd8765"; ++ algorithm hmac-md5; ++}; ++ ++controls { ++ inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; }; ++}; ++ ++view one { ++ match-clients { geoip asnum "AS100001"; }; ++ zone "example" { ++ type master; ++ file "example1.db"; ++ }; ++}; ++ ++view two { ++ match-clients { geoip asnum "AS100002"; }; ++ zone "example" { ++ type master; ++ file "example2.db"; ++ }; ++}; ++ ++view three { ++ match-clients { geoip asnum "AS100003"; }; ++ zone "example" { ++ type master; ++ file "example3.db"; ++ }; ++}; ++ ++view four { ++ match-clients { geoip asnum "AS100004"; }; ++ zone "example" { ++ type master; ++ file "example4.db"; ++ }; ++}; ++ ++view five { ++ match-clients { geoip asnum "AS100005"; }; ++ zone "example" { ++ type master; ++ file "example5.db"; ++ }; ++}; ++ ++view six { ++ match-clients { geoip asnum "AS100006"; }; ++ zone "example" { ++ type master; ++ file "example6.db"; ++ }; ++}; ++ ++view seven { ++ match-clients { geoip asnum "AS100007"; }; ++ zone "example" { ++ type master; ++ file "example7.db"; ++ }; ++}; ++ ++view none { ++ match-clients { any; }; ++ zone "example" { ++ type master; ++ file "example.db.in"; ++ }; ++}; +diff --git a/bin/tests/system/geoip/ns2/named11.conf b/bin/tests/system/geoip/ns2/named11.conf +new file mode 100644 +index 0000000..af87edf +--- /dev/null ++++ b/bin/tests/system/geoip/ns2/named11.conf +@@ -0,0 +1,104 @@ ++/* ++ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") ++ * ++ * 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 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. ++ */ ++ ++// NS2 ++ ++controls { /* empty */ }; ++ ++options { ++ query-source address 10.53.0.2; ++ notify-source 10.53.0.2; ++ transfer-source 10.53.0.2; ++ port 5300; ++ pid-file "named.pid"; ++ listen-on { 10.53.0.2; }; ++ listen-on-v6 { none; }; ++ recursion no; ++ geoip-directory "../data"; ++}; ++ ++key rndc_key { ++ secret "1234abcd8765"; ++ algorithm hmac-md5; ++}; ++ ++controls { ++ inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; }; ++}; ++ ++view one { ++ match-clients { geoip domain one.de; }; ++ zone "example" { ++ type master; ++ file "example1.db"; ++ }; ++}; ++ ++view two { ++ match-clients { geoip domain two.com; }; ++ zone "example" { ++ type master; ++ file "example2.db"; ++ }; ++}; ++ ++view three { ++ match-clients { geoip domain three.com; }; ++ zone "example" { ++ type master; ++ file "example3.db"; ++ }; ++}; ++ ++view four { ++ match-clients { geoip domain four.com; }; ++ zone "example" { ++ type master; ++ file "example4.db"; ++ }; ++}; ++ ++view five { ++ match-clients { geoip domain five.es; }; ++ zone "example" { ++ type master; ++ file "example5.db"; ++ }; ++}; ++ ++view six { ++ match-clients { geoip domain six.it; }; ++ zone "example" { ++ type master; ++ file "example6.db"; ++ }; ++}; ++ ++view seven { ++ match-clients { geoip domain seven.org; }; ++ zone "example" { ++ type master; ++ file "example7.db"; ++ }; ++}; ++ ++view none { ++ match-clients { any; }; ++ zone "example" { ++ type master; ++ file "example.db.in"; ++ }; ++}; +diff --git a/bin/tests/system/geoip/ns2/named12.conf b/bin/tests/system/geoip/ns2/named12.conf +new file mode 100644 +index 0000000..85c0d32 +--- /dev/null ++++ b/bin/tests/system/geoip/ns2/named12.conf +@@ -0,0 +1,80 @@ ++/* ++ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") ++ * ++ * 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 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. ++ */ ++ ++// NS2 ++ ++controls { /* empty */ }; ++ ++options { ++ query-source address 10.53.0.2; ++ notify-source 10.53.0.2; ++ transfer-source 10.53.0.2; ++ port 5300; ++ pid-file "named.pid"; ++ listen-on { 10.53.0.2; }; ++ listen-on-v6 { none; }; ++ recursion no; ++ geoip-directory "../data"; ++}; ++ ++key rndc_key { ++ secret "1234abcd8765"; ++ algorithm hmac-sha256; ++}; ++ ++controls { ++ inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; }; ++}; ++ ++view one { ++ match-clients { geoip netspeed 0; }; ++ zone "example" { ++ type master; ++ file "example1.db"; ++ }; ++}; ++ ++view two { ++ match-clients { geoip netspeed 1; }; ++ zone "example" { ++ type master; ++ file "example2.db"; ++ }; ++}; ++ ++view three { ++ match-clients { geoip netspeed 2; }; ++ zone "example" { ++ type master; ++ file "example3.db"; ++ }; ++}; ++ ++view four { ++ match-clients { geoip netspeed 3; }; ++ zone "example" { ++ type master; ++ file "example4.db"; ++ }; ++}; ++ ++view none { ++ match-clients { any; }; ++ zone "example" { ++ type master; ++ file "example.db.in"; ++ }; ++}; +diff --git a/bin/tests/system/geoip/ns2/named13.conf b/bin/tests/system/geoip/ns2/named13.conf +new file mode 100644 +index 0000000..a650a63 +--- /dev/null ++++ b/bin/tests/system/geoip/ns2/named13.conf +@@ -0,0 +1,45 @@ ++/* ++ * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") ++ * ++ * 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 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. ++ */ ++ ++// NS2 ++ ++controls { /* empty */ }; ++ ++acl blocking { ++ geoip db country country AU; ++}; ++ ++options { ++ query-source address 10.53.0.2; ++ notify-source 10.53.0.2; ++ transfer-source 10.53.0.2; ++ port 5300; ++ pid-file "named.pid"; ++ listen-on { 10.53.0.2; }; ++ listen-on-v6 { none; }; ++ recursion no; ++ geoip-directory "../data"; ++ blackhole { blocking; }; ++}; ++ ++key rndc_key { ++ secret "1234abcd8765"; ++ algorithm hmac-sha256; ++}; ++ ++controls { ++ inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; }; ++}; +diff --git a/bin/tests/system/geoip/ns2/named14.conf b/bin/tests/system/geoip/ns2/named14.conf +new file mode 100644 +index 0000000..f92d252 +--- /dev/null ++++ b/bin/tests/system/geoip/ns2/named14.conf +@@ -0,0 +1,112 @@ ++/* ++ * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") ++ * ++ * 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 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. ++ */ ++ ++// NS2 ++ ++controls { /* empty */ }; ++ ++options { ++ query-source address 10.53.0.2; ++ notify-source 10.53.0.2; ++ transfer-source 10.53.0.2; ++ port 5300; ++ pid-file "named.pid"; ++ listen-on { 10.53.0.2; }; ++ listen-on-v6 { none; }; ++ recursion no; ++ geoip-directory "../data"; ++}; ++ ++key rndc_key { ++ secret "1234abcd8765"; ++ algorithm hmac-sha256; ++}; ++ ++controls { ++ inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; }; ++}; ++ ++acl gAU { geoip db country country AU; }; ++acl gUS { geoip db country country US; }; ++acl gGB { geoip db country country GB; }; ++acl gCA { geoip db country country CA; }; ++acl gCL { geoip db country country CL; }; ++acl gDE { geoip db country country DE; }; ++acl gEH { geoip db country country EH; }; ++ ++view one { ++ match-clients { gAU; }; ++ zone "example" { ++ type master; ++ file "example1.db"; ++ }; ++}; ++ ++view two { ++ match-clients { gUS; }; ++ zone "example" { ++ type master; ++ file "example2.db"; ++ }; ++}; ++ ++view three { ++ match-clients { gGB; }; ++ zone "example" { ++ type master; ++ file "example3.db"; ++ }; ++}; ++ ++view four { ++ match-clients { gCA; }; ++ zone "example" { ++ type master; ++ file "example4.db"; ++ }; ++}; ++ ++view five { ++ match-clients { gCL; }; ++ zone "example" { ++ type master; ++ file "example5.db"; ++ }; ++}; ++ ++view six { ++ match-clients { gDE; }; ++ zone "example" { ++ type master; ++ file "example6.db"; ++ }; ++}; ++ ++view seven { ++ match-clients { gEH; }; ++ zone "example" { ++ type master; ++ file "example7.db"; ++ }; ++}; ++ ++view none { ++ match-clients { any; }; ++ zone "example" { ++ type master; ++ file "example.db.in"; ++ }; ++}; +diff --git a/bin/tests/system/geoip/ns2/named15.conf b/bin/tests/system/geoip/ns2/named15.conf +new file mode 100644 +index 0000000..6ac837b +--- /dev/null ++++ b/bin/tests/system/geoip/ns2/named15.conf +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") ++ * ++ * 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 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. ++ */ ++ ++// NS2 ++ ++controls { /* empty */ }; ++ ++options { ++ query-source address 10.53.0.2; ++ notify-source 10.53.0.2; ++ transfer-source 10.53.0.2; ++ port 5300; ++ pid-file "named.pid"; ++ listen-on { 10.53.0.2; }; ++ listen-on-v6 { fd92:7065:b8e:ffff::2; }; ++ recursion no; ++ geoip-directory "../data2"; ++}; ++ ++key rndc_key { ++ secret "1234abcd8765"; ++ algorithm hmac-sha256; ++}; ++ ++controls { ++ inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; }; ++}; ++ ++view two { ++ match-clients { geoip country US; }; ++ zone "example" { ++ type master; ++ file "../ns2/example2.db"; ++ }; ++}; ++ ++view none { ++ zone "example" { ++ type master; ++ file "examplebogus.db"; ++ }; ++}; +diff --git a/bin/tests/system/geoip/ns2/named2.conf b/bin/tests/system/geoip/ns2/named2.conf +new file mode 100644 +index 0000000..67a5155 +--- /dev/null ++++ b/bin/tests/system/geoip/ns2/named2.conf +@@ -0,0 +1,104 @@ ++/* ++ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") ++ * ++ * 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 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. ++ */ ++ ++// NS2 ++ ++controls { /* empty */ }; ++ ++options { ++ query-source address 10.53.0.2; ++ notify-source 10.53.0.2; ++ transfer-source 10.53.0.2; ++ port 5300; ++ pid-file "named.pid"; ++ listen-on { 10.53.0.2; }; ++ listen-on-v6 { none; }; ++ recursion no; ++ geoip-directory "../data"; ++}; ++ ++key rndc_key { ++ secret "1234abcd8765"; ++ algorithm hmac-md5; ++}; ++ ++controls { ++ inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; }; ++}; ++ ++view one { ++ match-clients { geoip db country country AUS; }; ++ zone "example" { ++ type master; ++ file "example1.db"; ++ }; ++}; ++ ++view two { ++ match-clients { geoip db country country USA; }; ++ zone "example" { ++ type master; ++ file "example2.db"; ++ }; ++}; ++ ++view three { ++ match-clients { geoip db country country GBR; }; ++ zone "example" { ++ type master; ++ file "example3.db"; ++ }; ++}; ++ ++view four { ++ match-clients { geoip db country country CAN; }; ++ zone "example" { ++ type master; ++ file "example4.db"; ++ }; ++}; ++ ++view five { ++ match-clients { geoip db country country CHL; }; ++ zone "example" { ++ type master; ++ file "example5.db"; ++ }; ++}; ++ ++view six { ++ match-clients { geoip db country country DEU; }; ++ zone "example" { ++ type master; ++ file "example6.db"; ++ }; ++}; ++ ++view seven { ++ match-clients { geoip db country country ESH; }; ++ zone "example" { ++ type master; ++ file "example7.db"; ++ }; ++}; ++ ++view none { ++ match-clients { any; }; ++ zone "example" { ++ type master; ++ file "example.db.in"; ++ }; ++}; +diff --git a/bin/tests/system/geoip/ns2/named3.conf b/bin/tests/system/geoip/ns2/named3.conf +new file mode 100644 +index 0000000..65113a6 +--- /dev/null ++++ b/bin/tests/system/geoip/ns2/named3.conf +@@ -0,0 +1,104 @@ ++/* ++ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") ++ * ++ * 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 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. ++ */ ++ ++// NS2 ++ ++controls { /* empty */ }; ++ ++options { ++ query-source address 10.53.0.2; ++ notify-source 10.53.0.2; ++ transfer-source 10.53.0.2; ++ port 5300; ++ pid-file "named.pid"; ++ listen-on { 10.53.0.2; }; ++ listen-on-v6 { none; }; ++ recursion no; ++ geoip-directory "../data"; ++}; ++ ++key rndc_key { ++ secret "1234abcd8765"; ++ algorithm hmac-md5; ++}; ++ ++controls { ++ inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; }; ++}; ++ ++view one { ++ match-clients { geoip db country country Australia; }; ++ zone "example" { ++ type master; ++ file "example1.db"; ++ }; ++}; ++ ++view two { ++ match-clients { geoip db country country "United States"; }; ++ zone "example" { ++ type master; ++ file "example2.db"; ++ }; ++}; ++ ++view three { ++ match-clients { geoip db country country "United Kingdom"; }; ++ zone "example" { ++ type master; ++ file "example3.db"; ++ }; ++}; ++ ++view four { ++ match-clients { geoip db country country Canada; }; ++ zone "example" { ++ type master; ++ file "example4.db"; ++ }; ++}; ++ ++view five { ++ match-clients { geoip db country country Chile; }; ++ zone "example" { ++ type master; ++ file "example5.db"; ++ }; ++}; ++ ++view six { ++ match-clients { geoip db country country Germany; }; ++ zone "example" { ++ type master; ++ file "example6.db"; ++ }; ++}; ++ ++view seven { ++ match-clients { geoip db country country "Western Sahara"; }; ++ zone "example" { ++ type master; ++ file "example7.db"; ++ }; ++}; ++ ++view none { ++ match-clients { any; }; ++ zone "example" { ++ type master; ++ file "example.db.in"; ++ }; ++}; +diff --git a/bin/tests/system/geoip/ns2/named4.conf b/bin/tests/system/geoip/ns2/named4.conf +new file mode 100644 +index 0000000..d2393d5 +--- /dev/null ++++ b/bin/tests/system/geoip/ns2/named4.conf +@@ -0,0 +1,96 @@ ++/* ++ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") ++ * ++ * 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 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. ++ */ ++ ++// NS2 ++ ++controls { /* empty */ }; ++ ++options { ++ query-source address 10.53.0.2; ++ notify-source 10.53.0.2; ++ transfer-source 10.53.0.2; ++ port 5300; ++ pid-file "named.pid"; ++ listen-on { 10.53.0.2; }; ++ listen-on-v6 { none; }; ++ recursion no; ++ geoip-directory "../data"; ++}; ++ ++key rndc_key { ++ secret "1234abcd8765"; ++ algorithm hmac-md5; ++}; ++ ++controls { ++ inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; }; ++}; ++ ++view one { ++ match-clients { geoip region CA; }; ++ zone "example" { ++ type master; ++ file "example1.db"; ++ }; ++}; ++ ++view three { ++ match-clients { geoip region OK; }; ++ zone "example" { ++ type master; ++ file "example3.db"; ++ }; ++}; ++ ++view four { ++ match-clients { geoip region VA; }; ++ zone "example" { ++ type master; ++ file "example4.db"; ++ }; ++}; ++ ++view five { ++ match-clients { geoip region GA; }; ++ zone "example" { ++ type master; ++ file "example5.db"; ++ }; ++}; ++ ++view six { ++ match-clients { geoip region CO; }; ++ zone "example" { ++ type master; ++ file "example6.db"; ++ }; ++}; ++ ++view seven { ++ match-clients { geoip region AK; }; ++ zone "example" { ++ type master; ++ file "example7.db"; ++ }; ++}; ++ ++view none { ++ match-clients { any; }; ++ zone "example" { ++ type master; ++ file "example.db.in"; ++ }; ++}; +diff --git a/bin/tests/system/geoip/ns2/named5.conf b/bin/tests/system/geoip/ns2/named5.conf +new file mode 100644 +index 0000000..011e310 +--- /dev/null ++++ b/bin/tests/system/geoip/ns2/named5.conf +@@ -0,0 +1,104 @@ ++/* ++ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") ++ * ++ * 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 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. ++ */ ++ ++// NS2 ++ ++controls { /* empty */ }; ++ ++options { ++ query-source address 10.53.0.2; ++ notify-source 10.53.0.2; ++ transfer-source 10.53.0.2; ++ port 5300; ++ pid-file "named.pid"; ++ listen-on { 10.53.0.2; }; ++ listen-on-v6 { none; }; ++ recursion no; ++ geoip-directory "../data"; ++}; ++ ++key rndc_key { ++ secret "1234abcd8765"; ++ algorithm hmac-md5; ++}; ++ ++controls { ++ inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; }; ++}; ++ ++view one { ++ match-clients { geoip db region region "California"; }; ++ zone "example" { ++ type master; ++ file "example1.db"; ++ }; ++}; ++ ++view two { ++ match-clients { geoip db region region "British Columbia"; }; ++ zone "example" { ++ type master; ++ file "example2.db"; ++ }; ++}; ++ ++view three { ++ match-clients { geoip db region region "Oklahoma"; }; ++ zone "example" { ++ type master; ++ file "example3.db"; ++ }; ++}; ++ ++view four { ++ match-clients { geoip db region country AU; }; ++ zone "example" { ++ type master; ++ file "example4.db"; ++ }; ++}; ++ ++view five { ++ match-clients { geoip db region region "Colorado"; }; ++ zone "example" { ++ type master; ++ file "example5.db"; ++ }; ++}; ++ ++view six { ++ match-clients { geoip db region region "Ontario"; }; ++ zone "example" { ++ type master; ++ file "example6.db"; ++ }; ++}; ++ ++view seven { ++ match-clients { geoip db region country NL; }; ++ zone "example" { ++ type master; ++ file "example7.db"; ++ }; ++}; ++ ++view none { ++ match-clients { any; }; ++ zone "example" { ++ type master; ++ file "example.db.in"; ++ }; ++}; +diff --git a/bin/tests/system/geoip/ns2/named6.conf b/bin/tests/system/geoip/ns2/named6.conf +new file mode 100644 +index 0000000..7ef7b19 +--- /dev/null ++++ b/bin/tests/system/geoip/ns2/named6.conf +@@ -0,0 +1,104 @@ ++/* ++ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") ++ * ++ * 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 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. ++ */ ++ ++// NS2 ++ ++controls { /* empty */ }; ++ ++options { ++ query-source address 10.53.0.2; ++ notify-source 10.53.0.2; ++ transfer-source 10.53.0.2; ++ port 5300; ++ pid-file "named.pid"; ++ listen-on { 10.53.0.2; }; ++ listen-on-v6 { fd92:7065:b8e:ffff::1; }; ++ recursion no; ++ geoip-directory "../data"; ++}; ++ ++key rndc_key { ++ secret "1234abcd8765"; ++ algorithm hmac-md5; ++}; ++ ++controls { ++ inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; }; ++}; ++ ++view one { ++ match-clients { geoip city "Redwood City"; }; ++ zone "example" { ++ type master; ++ file "example1.db"; ++ }; ++}; ++ ++view two { ++ match-clients { geoip city "Santa Cruz"; }; ++ zone "example" { ++ type master; ++ file "example2.db"; ++ }; ++}; ++ ++view three { ++ match-clients { geoip city "Oklahoma City"; }; ++ zone "example" { ++ type master; ++ file "example3.db"; ++ }; ++}; ++ ++view four { ++ match-clients { geoip city "Ashland"; }; ++ zone "example" { ++ type master; ++ file "example4.db"; ++ }; ++}; ++ ++view five { ++ match-clients { geoip city "Atlanta"; }; ++ zone "example" { ++ type master; ++ file "example5.db"; ++ }; ++}; ++ ++view six { ++ match-clients { geoip city "Morrison"; }; ++ zone "example" { ++ type master; ++ file "example6.db"; ++ }; ++}; ++ ++view seven { ++ match-clients { geoip city "Ketchikan"; }; ++ zone "example" { ++ type master; ++ file "example7.db"; ++ }; ++}; ++ ++view none { ++ match-clients { any; }; ++ zone "example" { ++ type master; ++ file "example.db.in"; ++ }; ++}; +diff --git a/bin/tests/system/geoip/ns2/named7.conf b/bin/tests/system/geoip/ns2/named7.conf +new file mode 100644 +index 0000000..118bdbe +--- /dev/null ++++ b/bin/tests/system/geoip/ns2/named7.conf +@@ -0,0 +1,104 @@ ++/* ++ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") ++ * ++ * 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 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. ++ */ ++ ++// NS2 ++ ++controls { /* empty */ }; ++ ++options { ++ query-source address 10.53.0.2; ++ notify-source 10.53.0.2; ++ transfer-source 10.53.0.2; ++ port 5300; ++ pid-file "named.pid"; ++ listen-on { 10.53.0.2; }; ++ listen-on-v6 { none; }; ++ recursion no; ++ geoip-directory "../data"; ++}; ++ ++key rndc_key { ++ secret "1234abcd8765"; ++ algorithm hmac-md5; ++}; ++ ++controls { ++ inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; }; ++}; ++ ++view one { ++ match-clients { geoip isp "One Systems, Inc."; }; ++ zone "example" { ++ type master; ++ file "example1.db"; ++ }; ++}; ++ ++view two { ++ match-clients { geoip isp "Two Technology Ltd."; }; ++ zone "example" { ++ type master; ++ file "example2.db"; ++ }; ++}; ++ ++view three { ++ match-clients { geoip isp "Three Network Labs"; }; ++ zone "example" { ++ type master; ++ file "example3.db"; ++ }; ++}; ++ ++view four { ++ match-clients { geoip isp "Four University"; }; ++ zone "example" { ++ type master; ++ file "example4.db"; ++ }; ++}; ++ ++view five { ++ match-clients { geoip isp "Five Telecom"; }; ++ zone "example" { ++ type master; ++ file "example5.db"; ++ }; ++}; ++ ++view six { ++ match-clients { geoip isp "Six Company"; }; ++ zone "example" { ++ type master; ++ file "example6.db"; ++ }; ++}; ++ ++view seven { ++ match-clients { geoip isp "Seven Communications"; }; ++ zone "example" { ++ type master; ++ file "example7.db"; ++ }; ++}; ++ ++view none { ++ match-clients { any; }; ++ zone "example" { ++ type master; ++ file "example.db.in"; ++ }; ++}; +diff --git a/bin/tests/system/geoip/ns2/named8.conf b/bin/tests/system/geoip/ns2/named8.conf +new file mode 100644 +index 0000000..9cb5c0a +--- /dev/null ++++ b/bin/tests/system/geoip/ns2/named8.conf +@@ -0,0 +1,104 @@ ++/* ++ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") ++ * ++ * 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 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. ++ */ ++ ++// NS2 ++ ++controls { /* empty */ }; ++ ++options { ++ query-source address 10.53.0.2; ++ notify-source 10.53.0.2; ++ transfer-source 10.53.0.2; ++ port 5300; ++ pid-file "named.pid"; ++ listen-on { 10.53.0.2; }; ++ listen-on-v6 { none; }; ++ recursion no; ++ geoip-directory "../data"; ++}; ++ ++key rndc_key { ++ secret "1234abcd8765"; ++ algorithm hmac-md5; ++}; ++ ++controls { ++ inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; }; ++}; ++ ++view one { ++ match-clients { geoip org "One Systems, Inc."; }; ++ zone "example" { ++ type master; ++ file "example1.db"; ++ }; ++}; ++ ++view two { ++ match-clients { geoip org "Two Technology Ltd."; }; ++ zone "example" { ++ type master; ++ file "example2.db"; ++ }; ++}; ++ ++view three { ++ match-clients { geoip org "Three Network Labs"; }; ++ zone "example" { ++ type master; ++ file "example3.db"; ++ }; ++}; ++ ++view four { ++ match-clients { geoip org "Four University"; }; ++ zone "example" { ++ type master; ++ file "example4.db"; ++ }; ++}; ++ ++view five { ++ match-clients { geoip org "Five Telecom"; }; ++ zone "example" { ++ type master; ++ file "example5.db"; ++ }; ++}; ++ ++view six { ++ match-clients { geoip org "Six Company"; }; ++ zone "example" { ++ type master; ++ file "example6.db"; ++ }; ++}; ++ ++view seven { ++ match-clients { geoip org "Seven Communications"; }; ++ zone "example" { ++ type master; ++ file "example7.db"; ++ }; ++}; ++ ++view none { ++ match-clients { any; }; ++ zone "example" { ++ type master; ++ file "example.db.in"; ++ }; ++}; +diff --git a/bin/tests/system/geoip/ns2/named9.conf b/bin/tests/system/geoip/ns2/named9.conf +new file mode 100644 +index 0000000..af2f7ff +--- /dev/null ++++ b/bin/tests/system/geoip/ns2/named9.conf +@@ -0,0 +1,104 @@ ++/* ++ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") ++ * ++ * 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 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. ++ */ ++ ++// NS2 ++ ++controls { /* empty */ }; ++ ++options { ++ query-source address 10.53.0.2; ++ notify-source 10.53.0.2; ++ transfer-source 10.53.0.2; ++ port 5300; ++ pid-file "named.pid"; ++ listen-on { 10.53.0.2; }; ++ listen-on-v6 { none; }; ++ recursion no; ++ geoip-directory "../data"; ++}; ++ ++key rndc_key { ++ secret "1234abcd8765"; ++ algorithm hmac-md5; ++}; ++ ++controls { ++ inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; }; ++}; ++ ++view one { ++ match-clients { geoip asnum "AS100001 One Systems, Inc."; }; ++ zone "example" { ++ type master; ++ file "example1.db"; ++ }; ++}; ++ ++view two { ++ match-clients { geoip asnum "AS100002 Two Technology Ltd."; }; ++ zone "example" { ++ type master; ++ file "example2.db"; ++ }; ++}; ++ ++view three { ++ match-clients { geoip asnum "AS100003 Three Network Labs"; }; ++ zone "example" { ++ type master; ++ file "example3.db"; ++ }; ++}; ++ ++view four { ++ match-clients { geoip asnum "AS100004 Four University"; }; ++ zone "example" { ++ type master; ++ file "example4.db"; ++ }; ++}; ++ ++view five { ++ match-clients { geoip asnum "AS100005 Five Telecom"; }; ++ zone "example" { ++ type master; ++ file "example5.db"; ++ }; ++}; ++ ++view six { ++ match-clients { geoip asnum "AS100006 Six Company"; }; ++ zone "example" { ++ type master; ++ file "example6.db"; ++ }; ++}; ++ ++view seven { ++ match-clients { geoip asnum "AS100007 Seven Communications"; }; ++ zone "example" { ++ type master; ++ file "example7.db"; ++ }; ++}; ++ ++view none { ++ match-clients { any; }; ++ zone "example" { ++ type master; ++ file "example.db.in"; ++ }; ++}; +diff --git a/bin/tests/system/geoip/options.conf b/bin/tests/system/geoip/options.conf +new file mode 100644 +index 0000000..b4d46cb +--- /dev/null ++++ b/bin/tests/system/geoip/options.conf +@@ -0,0 +1,42 @@ ++/* ++ * Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC") ++ * ++ * 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 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. ++ */ ++ ++// NS2 ++ ++controls { /* empty */ }; ++ ++options { ++ query-source address 10.53.0.2; ++ notify-source 10.53.0.2; ++ transfer-source 10.53.0.2; ++ port 5300; ++ pid-file "named.pid"; ++ listen-on { 10.53.0.2; }; ++ listen-on-v6 { none; }; ++ recursion no; ++ geoip-directory "data"; ++ allow-query { ++ geoip area 831; ++ geoip areacode 831; ++ geoip metro 828; ++ geoip metrocode 828; ++ geoip tz PST; ++ geoip timezone PST; ++ geoip postal 95060; ++ geoip postalcode 95060; ++ }; ++}; ++ +diff --git a/bin/tests/system/geoip/prereq.sh b/bin/tests/system/geoip/prereq.sh +new file mode 100644 +index 0000000..b78be41 +--- /dev/null ++++ b/bin/tests/system/geoip/prereq.sh +@@ -0,0 +1,23 @@ ++#!/bin/sh ++# ++# Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") ++# ++# 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 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. ++ ++if ./geoip ++then ++ : ++else ++ echo "I:This test requires GeoIP support." >&2 ++ exit 1 ++fi +diff --git a/bin/tests/system/geoip/setup.sh b/bin/tests/system/geoip/setup.sh +new file mode 100644 +index 0000000..5c5e2ca +--- /dev/null ++++ b/bin/tests/system/geoip/setup.sh +@@ -0,0 +1,27 @@ ++#!/bin/sh ++# ++# Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") ++# ++# 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 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. ++ ++sh clean.sh ++ ++cp ns2/named1.conf ns2/named.conf ++ ++for i in 1 2 3 4 5 6 7 other bogus; do ++ cp ns2/example.db.in ns2/example${i}.db ++ echo "@ IN TXT \"$i\"" >> ns2/example$i.db ++done ++ ++mkdir -p data2 ++cp data/GeoIPv6.dat data2/ +diff --git a/bin/tests/system/geoip/tests.sh b/bin/tests/system/geoip/tests.sh +new file mode 100644 +index 0000000..07635b1 +--- /dev/null ++++ b/bin/tests/system/geoip/tests.sh +@@ -0,0 +1,328 @@ ++#!/bin/sh ++# ++# Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") ++# ++# 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 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. ++ ++SYSTEMTESTTOP=.. ++. $SYSTEMTESTTOP/conf.sh ++ ++status=0 ++n=0 ++ ++rm -f dig.out.* ++ ++DIGOPTS="+tcp +short -p 5300 @10.53.0.2" ++DIGOPTS6="+tcp +short -p 5300 @fd92:7065:b8e:ffff::2" ++ ++n=`expr $n + 1` ++echo "I:checking GeoIP country database by code ($n)" ++ret=0 ++lret=0 ++for i in 1 2 3 4 5 6 7; do ++ $DIG $DIGOPTS txt example -b 10.53.0.$i > dig.out.ns2.test$n.$i || lret=1 ++ j=`cat dig.out.ns2.test$n.$i | tr -d '"'` ++ [ "$i" = "$j" ] || lret=1 ++ [ $lret -eq 1 ] && break ++done ++[ $lret -eq 1 ] && ret=1 ++[ $ret -eq 0 ] || echo "I:failed" ++status=`expr $status + $ret` ++ ++echo "I:reloading server" ++cp -f ns2/named2.conf ns2/named.conf ++$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reload 2>&1 | sed 's/^/I:ns2 /' ++sleep 3 ++ ++n=`expr $n + 1` ++echo "I:checking GeoIP country database by three-letter code ($n)" ++ret=0 ++lret=0 ++for i in 1 2 3 4 5 6 7; do ++ $DIG $DIGOPTS txt example -b 10.53.0.$i > dig.out.ns2.test$n.$i || lret=1 ++ j=`cat dig.out.ns2.test$n.$i | tr -d '"'` ++ [ "$i" = "$j" ] || lret=1 ++ [ $lret -eq 1 ] && break ++done ++[ $lret -eq 1 ] && ret=1 ++[ $ret -eq 0 ] || echo "I:failed" ++status=`expr $status + $ret` ++ ++echo "I:reloading server" ++cp -f ns2/named3.conf ns2/named.conf ++$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reload 2>&1 | sed 's/^/I:ns2 /' ++sleep 3 ++ ++n=`expr $n + 1` ++echo "I:checking GeoIP country database by name ($n)" ++ret=0 ++lret=0 ++for i in 1 2 3 4 5 6 7; do ++ $DIG $DIGOPTS txt example -b 10.53.0.$i > dig.out.ns2.test$n.$i || lret=1 ++ j=`cat dig.out.ns2.test$n.$i | tr -d '"'` ++ [ "$i" = "$j" ] || lret=1 ++ [ $lret -eq 1 ] && break ++done ++[ $lret -eq 1 ] && ret=1 ++[ $ret -eq 0 ] || echo "I:failed" ++status=`expr $status + $ret` ++ ++echo "I:reloading server" ++cp -f ns2/named4.conf ns2/named.conf ++$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reload 2>&1 | sed 's/^/I:ns2 /' ++sleep 3 ++ ++n=`expr $n + 1` ++echo "I:checking GeoIP region code, no specified database ($n)" ++ret=0 ++lret=0 ++# skipping 2 on purpose here; it has the same region code as 1 ++for i in 1 3 4 5 6 7; do ++ $DIG $DIGOPTS txt example -b 10.53.0.$i > dig.out.ns2.test$n.$i || lret=1 ++ j=`cat dig.out.ns2.test$n.$i | tr -d '"'` ++ [ "$i" = "$j" ] || lret=1 ++ [ $lret -eq 1 ] && break ++done ++[ $lret -eq 1 ] && ret=1 ++[ $ret -eq 0 ] || echo "I:failed" ++status=`expr $status + $ret` ++ ++echo "I:reloading server" ++cp -f ns2/named5.conf ns2/named.conf ++$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reload 2>&1 | sed 's/^/I:ns2 /' ++sleep 3 ++ ++n=`expr $n + 1` ++echo "I:checking GeoIP region database by region name and country code ($n)" ++ret=0 ++lret=0 ++for i in 1 2 3 4 5 6 7; do ++ $DIG $DIGOPTS txt example -b 10.53.0.$i > dig.out.ns2.test$n.$i || lret=1 ++ j=`cat dig.out.ns2.test$n.$i | tr -d '"'` ++ [ "$i" = "$j" ] || lret=1 ++ [ $lret -eq 1 ] && break ++done ++[ $lret -eq 1 ] && ret=1 ++[ $ret -eq 0 ] || echo "I:failed" ++status=`expr $status + $ret` ++ ++echo "I:reloading server" ++cp -f ns2/named6.conf ns2/named.conf ++$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reload 2>&1 | sed 's/^/I:ns2 /' ++sleep 3 ++ ++if $TESTSOCK6 fd92:7065:b8e:ffff::3 ++then ++ n=`expr $n + 1` ++ echo "I:checking GeoIP city database by city name using IPv6 ($n)" ++ ret=0 ++ $DIG +tcp +short -p 5300 @fd92:7065:b8e:ffff::1 -6 txt example -b fd92:7065:b8e:ffff::2 > dig.out.ns2.test$n || ret=1 ++ [ $ret -eq 0 ] || echo "I:failed" ++ status=`expr $status + $ret` ++else ++ echo "I:IPv6 unavailable; skipping" ++fi ++ ++n=`expr $n + 1` ++echo "I:checking GeoIP city database by city name ($n)" ++ret=0 ++lret=0 ++for i in 1 2 3 4 5 6 7; do ++ $DIG $DIGOPTS txt example -b 10.53.0.$i > dig.out.ns2.test$n.$i || lret=1 ++ j=`cat dig.out.ns2.test$n.$i | tr -d '"'` ++ [ "$i" = "$j" ] || lret=1 ++ [ $lret -eq 1 ] && break ++done ++[ $lret -eq 1 ] && ret=1 ++[ $ret -eq 0 ] || echo "I:failed" ++status=`expr $status + $ret` ++ ++echo "I:reloading server" ++cp -f ns2/named7.conf ns2/named.conf ++$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reload 2>&1 | sed 's/^/I:ns2 /' ++sleep 3 ++ ++n=`expr $n + 1` ++echo "I:checking GeoIP isp database ($n)" ++ret=0 ++lret=0 ++for i in 1 2 3 4 5 6 7; do ++ $DIG $DIGOPTS txt example -b 10.53.0.$i > dig.out.ns2.test$n.$i || lret=1 ++ j=`cat dig.out.ns2.test$n.$i | tr -d '"'` ++ [ "$i" = "$j" ] || lret=1 ++ [ $lret -eq 1 ] && break ++done ++[ $lret -eq 1 ] && ret=1 ++[ $ret -eq 0 ] || echo "I:failed" ++status=`expr $status + $ret` ++ ++echo "I:reloading server" ++cp -f ns2/named8.conf ns2/named.conf ++$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reload 2>&1 | sed 's/^/I:ns2 /' ++sleep 3 ++ ++n=`expr $n + 1` ++echo "I:checking GeoIP org database ($n)" ++ret=0 ++lret=0 ++for i in 1 2 3 4 5 6 7; do ++ $DIG $DIGOPTS txt example -b 10.53.0.$i > dig.out.ns2.test$n.$i || lret=1 ++ j=`cat dig.out.ns2.test$n.$i | tr -d '"'` ++ [ "$i" = "$j" ] || lret=1 ++ [ $lret -eq 1 ] && break ++done ++[ $lret -eq 1 ] && ret=1 ++[ $ret -eq 0 ] || echo "I:failed" ++status=`expr $status + $ret` ++ ++echo "I:reloading server" ++cp -f ns2/named9.conf ns2/named.conf ++$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reload 2>&1 | sed 's/^/I:ns2 /' ++sleep 3 ++ ++n=`expr $n + 1` ++echo "I:checking GeoIP asnum database ($n)" ++ret=0 ++lret=0 ++for i in 1 2 3 4 5 6 7; do ++ $DIG $DIGOPTS txt example -b 10.53.0.$i > dig.out.ns2.test$n.$i || lret=1 ++ j=`cat dig.out.ns2.test$n.$i | tr -d '"'` ++ [ "$i" = "$j" ] || lret=1 ++ [ $lret -eq 1 ] && break ++done ++[ $lret -eq 1 ] && ret=1 ++[ $ret -eq 0 ] || echo "I:failed" ++status=`expr $status + $ret` ++ ++echo "I:reloading server" ++cp -f ns2/named10.conf ns2/named.conf ++$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reload 2>&1 | sed 's/^/I:ns2 /' ++sleep 3 ++ ++n=`expr $n + 1` ++echo "I:checking GeoIP asnum database - ASNNNN only ($n)" ++ret=0 ++lret=0 ++for i in 1 2 3 4 5 6 7; do ++ $DIG $DIGOPTS txt example -b 10.53.0.$i > dig.out.ns2.test$n.$i || lret=1 ++ j=`cat dig.out.ns2.test$n.$i | tr -d '"'` ++ [ "$i" = "$j" ] || lret=1 ++ [ $lret -eq 1 ] && break ++done ++[ $lret -eq 1 ] && ret=1 ++[ $ret -eq 0 ] || echo "I:failed" ++status=`expr $status + $ret` ++ ++echo "I:reloading server" ++cp -f ns2/named11.conf ns2/named.conf ++$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reload 2>&1 | sed 's/^/I:ns2 /' ++sleep 3 ++ ++n=`expr $n + 1` ++echo "I:checking GeoIP domain database ($n)" ++ret=0 ++lret=0 ++for i in 1 2 3 4 5 6 7; do ++ $DIG $DIGOPTS txt example -b 10.53.0.$i > dig.out.ns2.test$n.$i || lret=1 ++ j=`cat dig.out.ns2.test$n.$i | tr -d '"'` ++ [ "$i" = "$j" ] || lret=1 ++ [ $lret -eq 1 ] && break ++done ++[ $lret -eq 1 ] && ret=1 ++[ $ret -eq 0 ] || echo "I:failed" ++status=`expr $status + $ret` ++ ++echo "I:reloading server" ++cp -f ns2/named12.conf ns2/named.conf ++$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reload 2>&1 | sed 's/^/I:ns2 /' ++sleep 3 ++ ++n=`expr $n + 1` ++echo "I:checking GeoIP netspeed database ($n)" ++ret=0 ++lret=0 ++for i in 1 2 3 4; do ++ $DIG $DIGOPTS txt example -b 10.53.0.$i > dig.out.ns2.test$n.$i || lret=1 ++ j=`cat dig.out.ns2.test$n.$i | tr -d '"'` ++ [ "$i" = "$j" ] || lret=1 ++ [ $lret -eq 1 ] && break ++done ++[ $lret -eq 1 ] && ret=1 ++[ $ret -eq 0 ] || echo "I:failed" ++status=`expr $status + $ret` ++ ++echo "I:reloading server" ++cp -f ns2/named13.conf ns2/named.conf ++$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reload 2>&1 | sed 's/^/I:ns2 /' ++sleep 3 ++ ++n=`expr $n + 1` ++echo "I:checking GeoIP blackhole ACL ($n)" ++ret=0 ++$DIG $DIGOPTS txt example -b 10.53.0.$i > dig.out.ns2.test$n || ret=1 ++$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 status 2>&1 > rndc.out.ns2.test$n || ret=1 ++[ $ret -eq 0 ] || echo "I:failed" ++status=`expr $status + $ret` ++ ++echo "I:reloading server" ++cp -f ns2/named14.conf ns2/named.conf ++$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reload 2>&1 | sed 's/^/I:ns2 /' ++sleep 3 ++ ++n=`expr $n + 1` ++echo "I:checking GeoIP country database by code (using nested ACLs) ($n)" ++ret=0 ++lret=0 ++for i in 1 2 3 4 5 6 7; do ++ $DIG $DIGOPTS txt example -b 10.53.0.$i > dig.out.ns2.test$n.$i || lret=1 ++ j=`cat dig.out.ns2.test$n.$i | tr -d '"'` ++ [ "$i" = "$j" ] || lret=1 ++ [ $lret -eq 1 ] && break ++done ++[ $lret -eq 1 ] && ret=1 ++[ $ret -eq 0 ] || echo "I:failed" ++status=`expr $status + $ret` ++ ++n=`expr $n + 1` ++echo "I:reloading server with different geoip-directory ($n)" ++ret=0 ++cp -f ns2/named15.conf ns2/named.conf ++$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reload 2>&1 | sed 's/^/I:ns2 /' ++sleep 3 ++awk '/using "..\/data2" as GeoIP directory/ {m=1} ; { if (m>0) { print } }' ns2/named.run | grep "GeoIP City .* DB not available" > /dev/null || ret=1 ++[ $ret -eq 0 ] || echo "I:failed" ++status=`expr $status + $ret` ++ ++n=`expr $n + 1` ++echo "I:checking GeoIP v4/v6 when only IPv6 database is available ($n)" ++ret=0 ++$DIG $DIGOPTS -4 txt example -b 10.53.0.2 > dig.out.ns2.test$n.1 || ret=1 ++j=`cat dig.out.ns2.test$n.1 | tr -d '"'` ++[ "$j" = "bogus" ] || ret=1 ++if $TESTSOCK6 fd92:7065:b8e:ffff::2; then ++ $DIG $DIGOPTS6 txt example -b fd92:7065:b8e:ffff::2 > dig.out.ns2.test$n.2 || ret=1 ++ j=`cat dig.out.ns2.test$n.2 | tr -d '"'` ++ [ "$j" = "2" ] || ret=1 ++fi ++[ $ret -eq 0 ] || echo "I:failed" ++status=`expr $status + $ret` ++ ++n=`expr $n + 1` ++echo "I:checking other GeoIP options are parsed correctly ($n)" ++ret=0 ++$CHECKCONF options.conf || ret=1 ++[ $ret -eq 0 ] || echo "I:failed" ++status=`expr $status + $ret` ++ ++echo "I:exit status: $status" ++exit $status +diff --git a/config.h.in b/config.h.in +index f2eb59a..6ed8381 100644 +--- a/config.h.in ++++ b/config.h.in +@@ -214,6 +214,15 @@ int sigwait(const unsigned int *set, int *sig); + /* Define to 1 if you have the header file. */ + #undef HAVE_FCNTL_H + ++/* Build with GeoIP support */ ++#undef HAVE_GEOIP ++ ++/* Build with GeoIP City IPv6 support */ ++#undef HAVE_GEOIP_CITY_V6 ++ ++/* Build with GeoIP Country IPv6 support */ ++#undef HAVE_GEOIP_V6 ++ + /* Define to 1 if you have the header file. */ + #undef HAVE_GSSAPI_GSSAPI_H + +diff --git a/configure.in b/configure.in +index 24eafb7..5b56172 100644 +--- a/configure.in ++++ b/configure.in +@@ -1252,6 +1252,99 @@ if test "$have_clock_gt" = "yes"; then + fi + + ++GEOIPLINKSRCS= ++GEOIPLINKOBJS= ++AC_ARG_WITH(geoip, ++[ --with-geoip=PATH Build with GeoIP support (yes|no|path)], ++ use_geoip="$withval", use_geoip="no") ++ ++if test "$use_geoip" = "yes" ++then ++ for d in /usr /usr/local /opt/local ++ do ++ if test -f $d/include/GeoIP.h ++ then ++ use_geoip=$d ++ break ++ fi ++ done ++fi ++ ++case "$use_geoip" in ++ no|'') ++ AC_MSG_CHECKING([for GeoIP support]) ++ AC_MSG_RESULT([disabled]) ++ ;; ++ *) ++ if test -d "$use_geoip" -o -L "$use_geoip" ++ then ++ CFLAGS="$CFLAGS -I$use_geoip/include" ++ CPPFLAGS="$CPPFLAGS -I$use_geoip/include" ++ LIBS="$LIBS -L$use_geoip/lib" ++ case "$host_os" in ++ netbsd*|openbsd*|solaris*) ++ LIBS="$LIBS -Wl,-rpath=$use_geoip/lib" ++ ;; ++ esac ++ elif test "$use_geoip" = "yes" ++ then ++ AC_MSG_ERROR([GeoIP path not found]) ++ else ++ AC_MSG_ERROR([GeoIP path $use_geoip does not exist]) ++ fi ++ AC_CHECK_HEADER(GeoIP.h, [], ++ [AC_MSG_ERROR([GeoIP header file not found])] ++ ) ++ AC_SEARCH_LIBS(GeoIP_open, GeoIP, [], ++ [AC_MSG_ERROR([GeoIP library not found])] ++ ) ++ AC_SEARCH_LIBS(fabsf, m, [], ++ [AC_MSG_ERROR([Math library not found])] ++ ) ++ AC_DEFINE(HAVE_GEOIP, 1, Build with GeoIP support) ++ GEOIPLINKSRCS='${GEOIPLINKSRCS}' ++ GEOIPLINKOBJS='${GEOIPLINKOBJS}' ++ AC_MSG_CHECKING([for GeoIP support]) ++ AC_MSG_RESULT([yes]) ++ ++ AC_MSG_CHECKING([for GeoIP Country IPv6 support]) ++ AC_COMPILE_IFELSE( ++ [AC_LANG_PROGRAM([ ++ #include ++ #include ++ ], [ ++ struct in6_addr in6; ++ GeoIP_country_name_by_ipnum_v6(NULL, in6); ++ ])], ++ [ ++ AC_MSG_RESULT([yes]) ++ AC_DEFINE(HAVE_GEOIP_V6, 1, Build with GeoIP Country IPv6 support) ++ ], ++ [AC_MSG_RESULT([no])] ++ ) ++ ++ AC_MSG_CHECKING([for GeoIP City IPv6 support]) ++ AC_COMPILE_IFELSE( ++ [AC_LANG_PROGRAM([ ++ #include ++ #include ++ #include ++ ], [ ++ struct in6_addr in6; ++ int i = GEOIP_CITY_EDITION_REV0_V6; ++ GeoIP_record_by_ipnum_v6(NULL, in6); ++ ])], ++ [ ++ AC_MSG_RESULT([yes]) ++ AC_DEFINE(HAVE_GEOIP_CITY_V6, 1, Build with GeoIP City IPv6 support) ++ ], ++ [AC_MSG_RESULT([no])] ++ ) ++ ;; ++esac ++AC_SUBST(GEOIPLINKSRCS) ++AC_SUBST(GEOIPLINKOBJS) ++ + AC_MSG_CHECKING(for GSSAPI library) + AC_ARG_WITH(gssapi, + [ --with-gssapi=PATH Specify path for system-supplied GSSAPI [[default=yes]]], +@@ -3962,6 +4055,7 @@ AC_CONFIG_FILES([ + bin/tests/system/dlzexternal/ns1/named.conf + bin/tests/system/ecdsa/prereq.sh + bin/tests/system/filter-aaaa/Makefile ++ bin/tests/system/geoip/Makefile + bin/tests/system/gost/prereq.sh + bin/tests/system/lwresd/Makefile + bin/tests/system/rpz/Makefile +diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml +index bd42e11..92c7b72 100644 +--- a/doc/arm/Bv9ARM-book.xml ++++ b/doc/arm/Bv9ARM-book.xml +@@ -3410,6 +3410,62 @@ $ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa. + + + ++ ++ When BIND 9 is built with GeoIP support, ++ ACLs can also be used for geographic access restrictions. ++ This is done by specifying an ACL element of the form: ++ geoip db database field value ++ ++ ++ The field indicates which field ++ to search for a match. Available fields are "country", ++ "region", "city", "continent", "postal" (postal code), ++ "metro" (metro code), "area" (area code), "tz" (timezone), ++ "isp", "org", "asnum", "domain" and "netspeed". ++ ++ ++ value is the value to searched for ++ within the database. A string may be quoted if it contains ++ spaces or other special characters. If this is a "country" ++ search and the string is two characters long, then it must be a ++ standard ISO-3166-1 two-letter country code, and if it is three ++ characters long then it must be an ISO-3166-1 three-letter ++ country code; otherwise it is the full name of the country. ++ Similarly, if this is a "region" search and the string is ++ two characters long, then it must be a standard two-letter state ++ or province abbreviation; otherwise it is the full name of the ++ state or province. ++ ++ ++ The database field indicates which ++ GeoIP database to search for a match. In most cases this is ++ unnecessary, because most search fields can only be found in ++ a single database. However, searches for country can be ++ answered from the "city", "region", or "country" databases, ++ and searches for region (i.e., state or provice) can be ++ answered from the "city" or "region" databases. For these ++ search types, specifying a database ++ will force the query to be answered from that database and no ++ other. If database is not ++ specified, then these queries will be answered from the "city", ++ database if it is installed, or the "region" database if it is ++ installed, or the "country" database, in that order. ++ ++ ++ Some example GeoIP ACLs: ++ ++ geoip country US; ++geoip country JAP; ++geoip db country country Canada; ++geoip db region region WA; ++geoip city "San Francisco"; ++geoip region Oklahoma; ++geoip postal 95062; ++geoip tz "America/Los_Angeles"; ++geoip org "Internet Systems Consortium"; ++ ++ ++ + + + <command>controls</command> Statement Grammar +@@ -4690,6 +4746,7 @@ badresp:1,adberr:0,findfail:0,valfail:0] + hostname hostname_string; + server-id server_id_string; + directory path_name; ++ geoip-directory path_name; + key-directory path_name; + managed-keys-directory path_name; + named-xfer path_name; +@@ -5046,6 +5103,21 @@ badresp:1,adberr:0,findfail:0,valfail:0] + + + ++ geoip-directory ++ ++ ++ Specifies the directory containing GeoIP ++ .dat database files for GeoIP ++ initialization. By default, this option is unset ++ and the GeoIP support will use libGeoIP's ++ built-in directory. ++ (For details, see about the ++ geoip ACL.) ++ ++ ++ ++ ++ + key-directory + + +diff --git a/lib/dns/Makefile.in b/lib/dns/Makefile.in +index 41fac95..0cc82f1 100644 +--- a/lib/dns/Makefile.in ++++ b/lib/dns/Makefile.in +@@ -56,6 +56,8 @@ DSTOBJS = @DST_EXTRA_OBJS@ @OPENSSLLINKOBJS@ @PKCS11LINKOBJS@ \ + + RRLOBJS = rrl.@O@ + ++GEOIPLINKOBJS = geoip.@O@ ++ + # Alphabetically + DNSOBJS = acache.@O@ acl.@O@ adb.@O@ byaddr.@O@ \ + cache.@O@ callbacks.@O@ clientinfo.@O@ compress.@O@ \ +@@ -75,7 +77,7 @@ DNSOBJS = acache.@O@ acl.@O@ adb.@O@ byaddr.@O@ \ + tsec.@O@ tsig.@O@ ttl.@O@ update.@O@ validator.@O@ \ + version.@O@ view.@O@ xfrin.@O@ zone.@O@ zonekey.@O@ zt.@O@ + +-OBJS= ${DNSOBJS} ${OTHEROBJS} ${DSTOBJS} @RRLLINKOBJS@ ++OBJS= ${DNSOBJS} ${OTHEROBJS} ${DSTOBJS} @RRLLINKOBJS@ @GEOIPLINKOBJS@ + + # Alphabetically + OPENSSLGOSTLINKSRCS = opensslgost_link.c +@@ -90,6 +92,8 @@ DSTSRCS = @DST_EXTRA_SRCS@ @OPENSSLLINKSRCS@ @PKCS11LINKSRCS@ \ + dst_result.c gssapi_link.c gssapictx.c \ + hmac_link.c key.c + ++GEOIOLINKSRCS = geoip.c ++ + DNSSRCS = acache.c acl.c adb.c byaddr.c \ + cache.c callbacks.c clientinfo.c compress.c \ + db.c dbiterator.c dbtable.c diff.c dispatch.c \ +@@ -107,7 +111,7 @@ DNSSRCS = acache.c acl.c adb.c byaddr.c \ + + RRLSRCS = rrl.c + +-SRCS = ${DSTSRCS} ${DNSSRCS} @RRLLINKSRCS@ ++SRCS = ${DSTSRCS} ${DNSSRCS} @RRLLINKSRCS@ @GEOIPLINKSRCS@ + + SUBDIRS = include + TARGETS = include/dns/enumtype.h include/dns/enumclass.h \ +diff --git a/lib/dns/acl.c b/lib/dns/acl.c +index 3221d30..aad9aa5 100644 +--- a/lib/dns/acl.c ++++ b/lib/dns/acl.c +@@ -29,6 +29,7 @@ + #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 +@@ -336,6 +337,14 @@ dns_acl_merge(dns_acl_t *dest, dns_acl_t *source, isc_boolean_t pos) + return result; + } + ++#ifdef HAVE_GEOIP ++ /* 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 == ISC_FALSE) { + dest->elements[nelem + i].negative = ISC_TRUE; +@@ -386,9 +395,8 @@ dns_aclelement_match(const isc_netaddr_t *reqaddr, + if (matchelt != NULL) + *matchelt = e; + return (ISC_TRUE); +- } else { ++ } else + return (ISC_FALSE); +- } + + case dns_aclelementtype_nestedacl: + inner = e->nestedacl; +@@ -406,6 +414,12 @@ dns_aclelement_match(const isc_netaddr_t *reqaddr, + inner = env->localnets; + break; + ++#ifdef HAVE_GEOIP ++ case dns_aclelementtype_geoip: ++ if (env == NULL || env->geoip == NULL) ++ return (ISC_FALSE); ++ return (dns_geoip_match(reqaddr, env->geoip, &e->geoip_elem)); ++#endif + default: + /* Should be impossible. */ + INSIST(0); +@@ -560,7 +574,7 @@ dns_acl_isinsecure(const dns_acl_t *a) { + insecure = insecure_prefix_found; + UNLOCK(&insecure_prefix_lock); + if (insecure) +- return(ISC_TRUE); ++ return (ISC_TRUE); + + /* Now check non-radix elements */ + for (i = 0; i < a->length; i++) { +@@ -609,6 +623,9 @@ dns_aclenv_init(isc_mem_t *mctx, dns_aclenv_t *env) { + if (result != ISC_R_SUCCESS) + goto cleanup_localhost; + env->match_mapped = ISC_FALSE; ++#ifdef HAVE_GEOIP ++ env->geoip = NULL; ++#endif + return (ISC_R_SUCCESS); + + cleanup_localhost: +diff --git a/lib/dns/geoip.c b/lib/dns/geoip.c +new file mode 100644 +index 0000000..5387ebb +--- /dev/null ++++ b/lib/dns/geoip.c +@@ -0,0 +1,820 @@ ++/* ++ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") ++ * ++ * 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 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 ++ ++#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 { ++ isc_uint16_t subtype; ++ unsigned int family; ++ isc_uint32_t ipnum; ++ geoipv6_t ipnum6; ++ 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 isc_boolean_t state_key_initialized = ISC_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, ISC_FALSE); ++ ++ ret = isc_thread_key_create(&state_key, free_state); ++ if (ret == 0) ++ state_key_initialized = ISC_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, isc_uint32_t ipnum, const geoipv6_t *ipnum6, ++ 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 ++ state->ipnum6 = *ipnum6; ++ ++ state->family = family; ++ state->subtype = subtype; ++ 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, isc_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, ++ isc_uint32_t ipnum, const geoipv6_t *ipnum6) ++{ ++ geoip_state_t *prev_state = NULL; ++ const char *text = 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 && prev_state->subtype == subtype) ++ text = prev_state->text; ++ ++ if (text == NULL) { ++ switch (subtype) { ++ case dns_geoip_country_code: ++ if (family == AF_INET) ++ text = GeoIP_country_code_by_ipnum(db, ipnum); ++#ifdef HAVE_GEOIP_V6 ++ else ++ text = GeoIP_country_code_by_ipnum_v6(db, ++ *ipnum6); ++#endif ++ break; ++ case dns_geoip_country_code3: ++ if (family == AF_INET) ++ text = GeoIP_country_code3_by_ipnum(db, ipnum); ++#ifdef HAVE_GEOIP_V6 ++ else ++ text = GeoIP_country_code3_by_ipnum_v6(db, ++ *ipnum6); ++#endif ++ break; ++ case dns_geoip_country_name: ++ if (family == AF_INET) ++ text = GeoIP_country_name_by_ipnum(db, ipnum); ++#ifdef HAVE_GEOIP_V6 ++ else ++ text = GeoIP_country_name_by_ipnum_v6(db, ++ *ipnum6); ++#endif ++ break; ++ default: ++ INSIST(0); ++ } ++ ++ set_state(family, ipnum, ipnum6, 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); ++ } ++} ++ ++static isc_boolean_t ++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 (ISC_TRUE); ++ default: ++ return (ISC_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, isc_uint32_t ipnum, const geoipv6_t *ipnum6) ++{ ++ 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 (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); ++ ++ set_state(family, ipnum, ipnum6, 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); ++ } ++} ++ ++static isc_boolean_t ++is_region(dns_geoip_subtype_t subtype) { ++ switch (subtype) { ++ case dns_geoip_region_countrycode: ++ case dns_geoip_region_code: ++ return (ISC_TRUE); ++ default: ++ return (ISC_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, isc_uint32_t ipnum) { ++ GeoIPRegion *region = NULL; ++ geoip_state_t *prev_state = NULL; ++ ++ 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 (region == NULL) { ++ region = GeoIP_region_by_ipnum(db, ipnum); ++ if (region == NULL) ++ return (NULL); ++ ++ set_state(AF_INET, ipnum, NULL, ++ 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, isc_uint32_t ipnum) { ++ char *name = NULL; ++ geoip_state_t *prev_state = NULL; ++ ++ 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 (name == NULL) { ++ name = GeoIP_name_by_ipnum(db, ipnum); ++ if (name == NULL) ++ return (NULL); ++ ++ set_state(AF_INET, ipnum, NULL, ++ 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, isc_uint32_t ipnum) { ++ geoip_state_t *prev_state = NULL; ++ isc_boolean_t found = ISC_FALSE; ++ 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; ++ found = ISC_TRUE; ++ } ++ ++ if (!found) { ++ id = GeoIP_id_by_ipnum(db, ipnum); ++ set_state(AF_INET, ipnum, NULL, ++ 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 */ ++ ++isc_boolean_t ++dns_geoip_match(const isc_netaddr_t *reqaddr, ++ const dns_geoip_databases_t *geoip, ++ const dns_geoip_elem_t *elt) ++{ ++#ifndef HAVE_GEOIP ++ UNUSED(reqaddr); ++ UNUSED(geoip); ++ UNUSED(elt); ++ ++ return (ISC_FALSE); ++#else ++ GeoIP *db; ++ GeoIPRecord *record; ++ GeoIPRegion *region; ++ dns_geoip_subtype_t subtype; ++ isc_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 (ISC_FALSE); ++#endif ++ default: ++ return (ISC_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 (ISC_FALSE); ++ ++ INSIST(elt->as_string != NULL); ++ ++ cs = country_lookup(db, subtype, family, ipnum, ipnum6); ++ if (cs != NULL && strncasecmp(elt->as_string, cs, maxlen) == 0) ++ return (ISC_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 (ISC_FALSE); ++ ++ record = city_lookup(db, subtype, family, ipnum, ipnum6); ++ if (record == NULL) ++ break; ++ ++ s = city_string(record, subtype, &maxlen); ++ INSIST(maxlen != 0); ++ if (s != NULL && strncasecmp(elt->as_string, s, maxlen) == 0) ++ return (ISC_TRUE); ++ break; ++ ++ case dns_geoip_city_metrocode: ++ db = DB46(reqaddr, geoip, city); ++ if (db == NULL) ++ return (ISC_FALSE); ++ ++ record = city_lookup(db, subtype, family, ipnum, ipnum6); ++ if (record == NULL) ++ break; ++ ++ if (elt->as_int == record->metro_code) ++ return (ISC_TRUE); ++ break; ++ ++ case dns_geoip_city_areacode: ++ db = DB46(reqaddr, geoip, city); ++ if (db == NULL) ++ return (ISC_FALSE); ++ ++ record = city_lookup(db, subtype, family, ipnum, ipnum6); ++ if (record == NULL) ++ break; ++ ++ if (elt->as_int == record->area_code) ++ return (ISC_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 (ISC_FALSE); ++ ++ INSIST(elt->as_string != NULL); ++ ++ /* Region DB is not supported for IPv6 */ ++ if (family == AF_INET6) ++ return (ISC_FALSE); ++ ++ region = region_lookup(geoip->region, subtype, ipnum); ++ if (region == NULL) ++ break; ++ ++ s = region_string(region, subtype, &maxlen); ++ INSIST(maxlen != 0); ++ if (s != NULL && strncasecmp(elt->as_string, s, maxlen) == 0) ++ return (ISC_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 (ISC_FALSE); ++ ++ INSIST(elt->as_string != NULL); ++ /* ISP, Org, AS, and Domain are not supported for IPv6 */ ++ if (family == AF_INET6) ++ return (ISC_FALSE); ++ ++ s = name_lookup(db, subtype, ipnum); ++ if (s != NULL) { ++ size_t l; ++ if (strcasecmp(elt->as_string, s) == 0) ++ return (ISC_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 (ISC_TRUE); ++ } ++ break; ++ ++ case dns_geoip_netspeed_id: ++ INSIST(geoip->netspeed != NULL); ++ ++ /* Netspeed DB is not supported for IPv6 */ ++ if (family == AF_INET6) ++ return (ISC_FALSE); ++ ++ id = netspeed_lookup(geoip->netspeed, subtype, ipnum); ++ if (id == elt->as_int) ++ return (ISC_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); ++ } ++ ++ return (ISC_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/include/dns/Makefile.in b/lib/dns/include/dns/Makefile.in +index 56172e9..1836fa3 100644 +--- a/lib/dns/include/dns/Makefile.in ++++ b/lib/dns/include/dns/Makefile.in +@@ -23,7 +23,7 @@ top_srcdir = @top_srcdir@ + + HEADERS = acl.h adb.h byaddr.h cache.h callbacks.h cert.h compress.h \ + clientinfo.h db.h dbiterator.h dbtable.h diff.h dispatch.h dynamic_db.h \ +- dlz.h dnssec.h ds.h events.h fixedname.h iptable.h journal.h \ ++ dlz.h dnssec.h ds.h events.h fixedname.h geoip.h iptable.h journal.h \ + keyflags.h keytable.h keyvalues.h lib.h log.h \ + master.h masterdump.h message.h name.h ncache.h nsec.h \ + peer.h portlist.h private.h rbt.h rcode.h \ +diff --git a/lib/dns/include/dns/acl.h b/lib/dns/include/dns/acl.h +index f4fc4a3..2c3bb37 100644 +--- a/lib/dns/include/dns/acl.h ++++ b/lib/dns/include/dns/acl.h +@@ -38,10 +38,17 @@ + #include + #include + ++#ifdef HAVE_GEOIP ++#include ++#endif + #include + #include + #include + ++#ifdef HAVE_GEOIP ++#include ++#endif ++ + /*** + *** Types + ***/ +@@ -52,8 +59,11 @@ typedef enum { + dns_aclelementtype_nestedacl, + dns_aclelementtype_localhost, + dns_aclelementtype_localnets, ++#ifdef HAVE_GEOIP ++ dns_aclelementtype_geoip, ++#endif /* HAVE_GEOIP */ + dns_aclelementtype_any +-} dns_aclelemettype_t; ++} dns_aclelementtype_t; + + typedef struct dns_aclipprefix dns_aclipprefix_t; + +@@ -63,9 +73,12 @@ struct dns_aclipprefix { + }; + + struct dns_aclelement { +- dns_aclelemettype_t type; ++ dns_aclelementtype_t type; + isc_boolean_t negative; + dns_name_t keyname; ++#ifdef HAVE_GEOIP ++ dns_geoip_elem_t geoip_elem; ++#endif /* HAVE_GEOIP */ + dns_acl_t *nestedacl; + int node_num; + }; +@@ -88,6 +101,9 @@ struct dns_aclenv { + dns_acl_t *localhost; + dns_acl_t *localnets; + isc_boolean_t match_mapped; ++#ifdef HAVE_GEOIP ++ dns_geoip_databases_t *geoip; ++#endif + }; + + #define DNS_ACL_MAGIC ISC_MAGIC('D','a','c','l') +@@ -214,6 +230,10 @@ dns_acl_match(const isc_netaddr_t *reqaddr, + * 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. + */ +diff --git a/lib/dns/include/dns/geoip.h b/lib/dns/include/dns/geoip.h +new file mode 100644 +index 0000000..bad9485 +--- /dev/null ++++ b/lib/dns/include/dns/geoip.h +@@ -0,0 +1,119 @@ ++/* ++ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") ++ * ++ * 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 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 DNS_GEOIP_H ++#define DNS_GEOIP_H 1 ++ ++/***** ++ ***** Module Info ++ *****/ ++ ++/*! \file dns/acl.h ++ * \brief ++ * Address match list handling. ++ */ ++ ++/*** ++ *** Imports ++ ***/ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#ifdef HAVE_GEOIP ++#include ++#else ++typedef void GeoIP; ++#endif ++ ++/*** ++ *** Types ++ ***/ ++ ++typedef enum { ++ dns_geoip_countrycode, ++ dns_geoip_countrycode3, ++ dns_geoip_countryname, ++ dns_geoip_region, ++ dns_geoip_regionname, ++ dns_geoip_country_code, ++ dns_geoip_country_code3, ++ dns_geoip_country_name, ++ 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_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; ++ GeoIP *db; ++ union { ++ char as_string[256]; ++ int as_int; ++ }; ++} dns_geoip_elem_t; ++ ++typedef struct dns_geoip_databases { ++ GeoIP *country_v4; /* DB 1 */ ++ GeoIP *city_v4; /* DB 2 or 6 */ ++ GeoIP *region; /* DB 3 or 7 */ ++ GeoIP *isp; /* DB 4 */ ++ GeoIP *org; /* DB 5 */ ++ GeoIP *as; /* DB 9 */ ++ GeoIP *netspeed; /* DB 10 */ ++ GeoIP *domain; /* DB 11 */ ++ GeoIP *country_v6; /* DB 12 */ ++ GeoIP *city_v6; /* DB 30 or 31 */ ++} dns_geoip_databases_t; ++ ++/*** ++ *** Functions ++ ***/ ++ ++ISC_LANG_BEGINDECLS ++ ++isc_boolean_t ++dns_geoip_match(const isc_netaddr_t *reqaddr, ++ const dns_geoip_databases_t *geoip, ++ const dns_geoip_elem_t *elt); ++ ++void ++dns_geoip_shutdown(void); ++ ++ISC_LANG_ENDDECLS ++#endif /* DNS_GEOIP_H */ +diff --git a/lib/dns/tests/Makefile.in b/lib/dns/tests/Makefile.in +index 3b19784..8d1b83e 100644 +--- a/lib/dns/tests/Makefile.in ++++ b/lib/dns/tests/Makefile.in +@@ -40,13 +40,13 @@ LIBS = @LIBS@ @ATFLIBS@ + OBJS = dnstest.@O@ + SRCS = dnstest.c gost_test.c master_test.c dbiterator_test.c time_test.c \ + private_test.c update_test.c zonemgr_test.c zt_test.c \ +- dbdiff_test.c dispatch_test.c nsec3_test.c \ ++ dbdiff_test.c geoip_test.c dispatch_test.c nsec3_test.c \ + rdataset_test.c rdata_test.c + + SUBDIRS = + TARGETS = gost_test@EXEEXT@ master_test@EXEEXT@ dbiterator_test@EXEEXT@ time_test@EXEEXT@ \ + private_test@EXEEXT@ update_test@EXEEXT@ zonemgr_test@EXEEXT@ \ +- zt_test@EXEEXT@ dbversion_test@EXEEXT@ dbdiff_test@EXEEXT@ \ ++ zt_test@EXEEXT@ dbversion_test@EXEEXT@ dbdiff_test@EXEEXT@ geoip_test@EXEEXT@ \ + dispatch_test@EXEEXT@ nsec3_test@EXEEXT@ \ + rdataset_test@EXEEXT@ rdata_test@EXEEXT@ + +@@ -129,6 +129,11 @@ gost_test@EXEEXT@: gost_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} + gost_test.@O@ dnstest.@O@ ${DNSLIBS} \ + ${ISCLIBS} ${LIBS} + ++geoip_test@EXEEXT@: geoip_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ++ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ ++ geoip_test.@O@ dnstest.@O@ ${DNSLIBS} \ ++ ${ISCLIBS} ${LIBS} ++ + unit:: + sh ${top_srcdir}/unit/unittest.sh + +diff --git a/lib/dns/tests/geoip_test.c b/lib/dns/tests/geoip_test.c +new file mode 100644 +index 0000000..ad983b0 +--- /dev/null ++++ b/lib/dns/tests/geoip_test.c +@@ -0,0 +1,694 @@ ++/* ++ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") ++ * ++ * 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 DISCLAIMS ALL WARRANTIES WITH ++ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ++ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, ++ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ++ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ++ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ++ * PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++/* $Id$ */ ++ ++/*! \file */ ++ ++#include ++ ++#include ++ ++#include ++ ++#include ++ ++#include ++ ++#include "dnstest.h" ++ ++#ifdef HAVE_GEOIP ++#include ++ ++/* We use GeoIP databases from the 'geoip' system test */ ++#define TEST_GEOIP_DATA "../../../bin/tests/system/geoip/data" ++ ++/* ++ * Helper functions ++ * (Mostly copied from bin/named/geoip.c) ++ */ ++static dns_geoip_databases_t geoip = { ++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ++}; ++ ++static void ++init_geoip_db(GeoIP **dbp, GeoIPDBTypes edition, GeoIPDBTypes fallback, ++ GeoIPOptions method, const char *name) ++{ ++ char *info; ++ GeoIP *db; ++ ++ REQUIRE(dbp != NULL); ++ ++ db = *dbp; ++ ++ if (db != NULL) { ++ GeoIP_delete(db); ++ db = *dbp = NULL; ++ } ++ ++ if (! GeoIP_db_avail(edition)) { ++ fprintf(stderr, "GeoIP %s (type %d) DB not available\n", ++ name, edition); ++ goto fail; ++ } ++ ++ fprintf(stderr, "initializing GeoIP %s (type %d) DB\n", ++ name, edition); ++ ++ db = GeoIP_open_type(edition, method); ++ if (db == NULL) { ++ fprintf(stderr, ++ "failed to initialize GeoIP %s (type %d) DB%s\n", ++ name, edition, fallback == 0 ++ ? "; geoip matches using this database will fail" ++ : ""); ++ goto fail; ++ } ++ ++ info = GeoIP_database_info(db); ++ if (info != NULL) ++ fprintf(stderr, "%s\n", info); ++ ++ *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 isc_boolean_t ++do_lookup_string(const char *addr, dns_geoip_subtype_t subtype, ++ const char *string) ++{ ++ 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; ++ strcpy(elt.as_string, string); ++ ++ return (dns_geoip_match(&na, &geoip, &elt)); ++} ++ ++static isc_boolean_t ++do_lookup_string_v6(const char *addr, dns_geoip_subtype_t subtype, ++ const char *string) ++{ ++ dns_geoip_elem_t elt; ++ struct in6_addr in6; ++ isc_netaddr_t na; ++ ++ inet_pton(AF_INET6, addr, &in6); ++ isc_netaddr_fromin6(&na, &in6); ++ ++ elt.subtype = subtype; ++ strcpy(elt.as_string, string); ++ ++ return (dns_geoip_match(&na, &geoip, &elt)); ++} ++ ++static isc_boolean_t ++do_lookup_int(const char *addr, 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, &geoip, &elt)); ++} ++ ++/* ++ * Individual unit tests ++ */ ++ ++/* GeoIP country matching */ ++ATF_TC(country); ++ATF_TC_HEAD(country, tc) { ++ atf_tc_set_md_var(tc, "descr", "test country database matching"); ++} ++ATF_TC_BODY(country, tc) { ++ isc_result_t result; ++ isc_boolean_t match; ++ ++ UNUSED(tc); ++ ++ result = dns_test_begin(NULL, ISC_TRUE); ++ ATF_REQUIRE(result == ISC_R_SUCCESS); ++ ++ /* Use databases from the geoip system test */ ++ load_geoip(TEST_GEOIP_DATA); ++ ++ if (geoip.country_v4 == NULL) { ++ dns_test_end(); ++ atf_tc_skip("Database not available"); ++ } ++ ++ match = do_lookup_string("10.53.0.1", dns_geoip_country_code, "AU"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_string("10.53.0.1", ++ dns_geoip_country_code3, "AUS"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_string("10.53.0.1", ++ dns_geoip_country_name, "Australia"); ++ ATF_CHECK(match); ++ ++ dns_test_end(); ++} ++ ++/* GeoIP country (ipv6) matching */ ++ATF_TC(country_v6); ++ATF_TC_HEAD(country_v6, tc) { ++ atf_tc_set_md_var(tc, "descr", "test country (ipv6) database matching"); ++} ++ATF_TC_BODY(country_v6, tc) { ++ isc_result_t result; ++ isc_boolean_t match; ++ ++ UNUSED(tc); ++ ++ result = dns_test_begin(NULL, ISC_TRUE); ++ ATF_REQUIRE(result == ISC_R_SUCCESS); ++ ++ /* Use databases from the geoip system test */ ++ load_geoip(TEST_GEOIP_DATA); ++ ++ if (geoip.country_v6 == NULL) { ++ dns_test_end(); ++ atf_tc_skip("Database not available"); ++ } ++ ++ match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", ++ dns_geoip_country_code, "AU"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", ++ dns_geoip_country_code3, "AUS"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", ++ dns_geoip_country_name, "Australia"); ++ ATF_CHECK(match); ++ ++ dns_test_end(); ++} ++ ++/* GeoIP city (ipv4) matching */ ++ATF_TC(city); ++ATF_TC_HEAD(city, tc) { ++ atf_tc_set_md_var(tc, "descr", "test city database matching"); ++} ++ATF_TC_BODY(city, tc) { ++ isc_result_t result; ++ isc_boolean_t match; ++ ++ UNUSED(tc); ++ ++ result = dns_test_begin(NULL, ISC_TRUE); ++ ATF_REQUIRE(result == ISC_R_SUCCESS); ++ ++ /* Use databases from the geoip system test */ ++ load_geoip(TEST_GEOIP_DATA); ++ ++ if (geoip.city_v4 == NULL) { ++ dns_test_end(); ++ atf_tc_skip("Database not available"); ++ } ++ ++ match = do_lookup_string("10.53.0.1", ++ dns_geoip_city_continentcode, "NA"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_string("10.53.0.1", ++ dns_geoip_city_countrycode, "US"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_string("10.53.0.1", ++ dns_geoip_city_countrycode3, "USA"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_string("10.53.0.1", ++ dns_geoip_city_countryname, "United States"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_string("10.53.0.1", ++ dns_geoip_city_region, "CA"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_string("10.53.0.1", ++ dns_geoip_city_regionname, "California"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_string("10.53.0.1", ++ dns_geoip_city_name, "Redwood City"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_string("10.53.0.1", ++ dns_geoip_city_postalcode, "94063"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_int("10.53.0.1", dns_geoip_city_areacode, 650); ++ ATF_CHECK(match); ++ ++ match = do_lookup_int("10.53.0.1", dns_geoip_city_metrocode, 807); ++ ATF_CHECK(match); ++ ++ dns_test_end(); ++} ++ ++/* GeoIP city (ipv6) matching */ ++ATF_TC(city_v6); ++ATF_TC_HEAD(city_v6, tc) { ++ atf_tc_set_md_var(tc, "descr", "test city (ipv6) database matching"); ++} ++ATF_TC_BODY(city_v6, tc) { ++ isc_result_t result; ++ isc_boolean_t match; ++ ++ UNUSED(tc); ++ ++ result = dns_test_begin(NULL, ISC_TRUE); ++ ATF_REQUIRE(result == ISC_R_SUCCESS); ++ ++ /* Use databases from the geoip system test */ ++ load_geoip(TEST_GEOIP_DATA); ++ ++ if (geoip.city_v6 == NULL) { ++ dns_test_end(); ++ atf_tc_skip("Database not available"); ++ } ++ ++ match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", ++ dns_geoip_city_continentcode, "NA"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", ++ dns_geoip_city_countrycode, "US"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", ++ dns_geoip_city_countrycode3, "USA"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", ++ dns_geoip_city_countryname, ++ "United States"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", ++ dns_geoip_city_region, "CA"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", ++ dns_geoip_city_regionname, "California"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", ++ dns_geoip_city_name, "Redwood City"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", ++ dns_geoip_city_postalcode, "94063"); ++ ATF_CHECK(match); ++ ++ dns_test_end(); ++} ++ ++ ++/* GeoIP region matching */ ++ATF_TC(region); ++ATF_TC_HEAD(region, tc) { ++ atf_tc_set_md_var(tc, "descr", "test region database matching"); ++} ++ATF_TC_BODY(region, tc) { ++ isc_result_t result; ++ isc_boolean_t match; ++ ++ UNUSED(tc); ++ ++ result = dns_test_begin(NULL, ISC_TRUE); ++ ATF_REQUIRE(result == ISC_R_SUCCESS); ++ ++ /* Use databases from the geoip system test */ ++ load_geoip(TEST_GEOIP_DATA); ++ ++ if (geoip.region == NULL) { ++ dns_test_end(); ++ atf_tc_skip("Database not available"); ++ } ++ ++ match = do_lookup_string("10.53.0.1", ++ dns_geoip_region_code, "CA"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_string("10.53.0.1", ++ dns_geoip_region_name, "California"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_string("10.53.0.1", ++ dns_geoip_region_countrycode, "US"); ++ ATF_CHECK(match); ++ ++ dns_test_end(); ++} ++ ++/* ++ * GeoIP best-database matching ++ * (With no specified databse and a city database available, answers ++ * should come from city database. With city database unavailable, region ++ * database. Region database unavailable, country database.) ++ */ ++ATF_TC(best); ++ATF_TC_HEAD(best, tc) { ++ atf_tc_set_md_var(tc, "descr", "test best database matching"); ++} ++ATF_TC_BODY(best, tc) { ++ isc_result_t result; ++ isc_boolean_t match; ++ ++ UNUSED(tc); ++ ++ result = dns_test_begin(NULL, ISC_TRUE); ++ ATF_REQUIRE(result == ISC_R_SUCCESS); ++ ++ /* Use databases from the geoip system test */ ++ load_geoip(TEST_GEOIP_DATA); ++ ++ if (geoip.region == NULL) { ++ dns_test_end(); ++ atf_tc_skip("Database not available"); ++ } ++ ++ match = do_lookup_string("10.53.0.4", ++ dns_geoip_countrycode, "US"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_string("10.53.0.4", ++ dns_geoip_countrycode3, "USA"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_string("10.53.0.4", ++ dns_geoip_countryname, "United States"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_string("10.53.0.4", ++ dns_geoip_regionname, "Virginia"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_string("10.53.0.4", ++ dns_geoip_region, "VA"); ++ ATF_CHECK(match); ++ ++ GeoIP_delete(geoip.city_v4); ++ geoip.city_v4 = NULL; ++ ++ match = do_lookup_string("10.53.0.4", ++ dns_geoip_countrycode, "AU"); ++ ATF_CHECK(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", ++ dns_geoip_countrycode3, "CAN"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_string("10.53.0.4", ++ dns_geoip_countryname, "Canada"); ++ ATF_CHECK(match); ++ ++ GeoIP_delete(geoip.region); ++ geoip.region = NULL; ++ ++ match = do_lookup_string("10.53.0.4", ++ dns_geoip_countrycode, "CA"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_string("10.53.0.4", ++ dns_geoip_countrycode3, "CAN"); ++ ATF_CHECK(match); ++ ++ match = do_lookup_string("10.53.0.4", ++ dns_geoip_countryname, "Canada"); ++ ATF_CHECK(match); ++ ++ dns_test_end(); ++} ++ ++ ++/* GeoIP asnum matching */ ++ATF_TC(asnum); ++ATF_TC_HEAD(asnum, tc) { ++ atf_tc_set_md_var(tc, "descr", "test asnum database matching"); ++} ++ATF_TC_BODY(asnum, tc) { ++ isc_result_t result; ++ isc_boolean_t match; ++ ++ UNUSED(tc); ++ ++ result = dns_test_begin(NULL, ISC_TRUE); ++ ATF_REQUIRE(result == ISC_R_SUCCESS); ++ ++ /* Use databases from the geoip system test */ ++ load_geoip(TEST_GEOIP_DATA); ++ ++ if (geoip.as == NULL) { ++ dns_test_end(); ++ atf_tc_skip("Database not available"); ++ } ++ ++ ++ match = do_lookup_string("10.53.0.3", dns_geoip_as_asnum, ++ "AS100003 Three Network Labs"); ++ ATF_CHECK(match); ++ ++ dns_test_end(); ++} ++ ++/* GeoIP isp matching */ ++ATF_TC(isp); ++ATF_TC_HEAD(isp, tc) { ++ atf_tc_set_md_var(tc, "descr", "test isp database matching"); ++} ++ATF_TC_BODY(isp, tc) { ++ isc_result_t result; ++ isc_boolean_t match; ++ ++ UNUSED(tc); ++ ++ result = dns_test_begin(NULL, ISC_TRUE); ++ ATF_REQUIRE(result == ISC_R_SUCCESS); ++ ++ /* Use databases from the geoip system test */ ++ load_geoip(TEST_GEOIP_DATA); ++ ++ if (geoip.isp == NULL) { ++ dns_test_end(); ++ atf_tc_skip("Database not available"); ++ } ++ ++ match = do_lookup_string("10.53.0.1", dns_geoip_isp_name, ++ "One Systems, Inc."); ++ ATF_CHECK(match); ++ ++ dns_test_end(); ++} ++ ++/* GeoIP org matching */ ++ATF_TC(org); ++ATF_TC_HEAD(org, tc) { ++ atf_tc_set_md_var(tc, "descr", "test org database matching"); ++} ++ATF_TC_BODY(org, tc) { ++ isc_result_t result; ++ isc_boolean_t match; ++ ++ UNUSED(tc); ++ ++ result = dns_test_begin(NULL, ISC_TRUE); ++ ATF_REQUIRE(result == ISC_R_SUCCESS); ++ ++ /* Use databases from the geoip system test */ ++ load_geoip(TEST_GEOIP_DATA); ++ ++ if (geoip.org == NULL) { ++ dns_test_end(); ++ atf_tc_skip("Database not available"); ++ } ++ ++ match = do_lookup_string("10.53.0.2", dns_geoip_org_name, ++ "Two Technology Ltd."); ++ ATF_CHECK(match); ++ ++ dns_test_end(); ++} ++ ++/* GeoIP domain matching */ ++ATF_TC(domain); ++ATF_TC_HEAD(domain, tc) { ++ atf_tc_set_md_var(tc, "descr", "test domain database matching"); ++} ++ATF_TC_BODY(domain, tc) { ++ isc_result_t result; ++ isc_boolean_t match; ++ ++ UNUSED(tc); ++ ++ result = dns_test_begin(NULL, ISC_TRUE); ++ ATF_REQUIRE(result == ISC_R_SUCCESS); ++ ++ /* Use databases from the geoip system test */ ++ load_geoip(TEST_GEOIP_DATA); ++ ++ if (geoip.domain == NULL) { ++ dns_test_end(); ++ atf_tc_skip("Database not available"); ++ } ++ ++ match = do_lookup_string("10.53.0.4", ++ dns_geoip_domain_name, "four.com"); ++ ATF_CHECK(match); ++ ++ dns_test_end(); ++} ++ ++/* GeoIP netspeed matching */ ++ATF_TC(netspeed); ++ATF_TC_HEAD(netspeed, tc) { ++ atf_tc_set_md_var(tc, "descr", "test netspeed database matching"); ++} ++ATF_TC_BODY(netspeed, tc) { ++ isc_result_t result; ++ isc_boolean_t match; ++ ++ UNUSED(tc); ++ ++ result = dns_test_begin(NULL, ISC_TRUE); ++ ATF_REQUIRE(result == ISC_R_SUCCESS); ++ ++ /* Use databases from the geoip system test */ ++ load_geoip(TEST_GEOIP_DATA); ++ ++ if (geoip.netspeed == NULL) { ++ dns_test_end(); ++ atf_tc_skip("Database not available"); ++ } ++ ++ match = do_lookup_int("10.53.0.1", dns_geoip_netspeed_id, 0); ++ ATF_CHECK(match); ++ ++ match = do_lookup_int("10.53.0.2", dns_geoip_netspeed_id, 1); ++ ATF_CHECK(match); ++ ++ match = do_lookup_int("10.53.0.3", dns_geoip_netspeed_id, 2); ++ ATF_CHECK(match); ++ ++ match = do_lookup_int("10.53.0.4", dns_geoip_netspeed_id, 3); ++ ATF_CHECK(match); ++ ++ dns_test_end(); ++} ++#else ++ATF_TC(untested); ++ATF_TC_HEAD(untested, tc) { ++ atf_tc_set_md_var(tc, "descr", "skipping geoip test"); ++} ++ATF_TC_BODY(untested, tc) { ++ UNUSED(tc); ++ atf_tc_skip("GeoIP not available"); ++} ++#endif ++ ++/* ++ * Main ++ */ ++ATF_TP_ADD_TCS(tp) { ++#ifdef HAVE_GEOIP ++ ATF_TP_ADD_TC(tp, country); ++ ATF_TP_ADD_TC(tp, country_v6); ++ ATF_TP_ADD_TC(tp, city); ++ ATF_TP_ADD_TC(tp, city_v6); ++ ATF_TP_ADD_TC(tp, region); ++ ATF_TP_ADD_TC(tp, best); ++ ATF_TP_ADD_TC(tp, asnum); ++ ATF_TP_ADD_TC(tp, isp); ++ ATF_TP_ADD_TC(tp, org); ++ ATF_TP_ADD_TC(tp, domain); ++ ATF_TP_ADD_TC(tp, netspeed); ++#else ++ ATF_TP_ADD_TC(tp, untested); ++#endif ++ ++ return (atf_no_error()); ++} ++ +diff --git a/lib/export/dns/Makefile.in b/lib/export/dns/Makefile.in +index e10bf59..54e4e39 100644 +--- a/lib/export/dns/Makefile.in ++++ b/lib/export/dns/Makefile.in +@@ -67,8 +65,9 @@ DNSOBJS = acl.@O@ adb.@O@ byaddr.@O@ \ + tcpmsg.@O@ time.@O@ tsec.@O@ tsig.@O@ ttl.@O@ \ + validator.@O@ version.@O@ view.@O@ + PORTDNSOBJS = ecdb.@O@ ++GEOIPLINKOBJS = geoip.@O@ + +-OBJS= ${DNSOBJS} ${OTHEROBJS} ${DSTOBJS} ${PORTDNSOBJS} ++OBJS= ${DNSOBJS} ${OTHEROBJS} ${DSTOBJS} ${PORTDNSOBJS} @GEOIPLINKOBJS@ + + # Alphabetically + +@@ -96,8 +93,9 @@ DNSSRCS = acl.c adb.c byaddr.c \ + tcpmsg.c time.c tsec.c tsig.c ttl.c \ + validator.c version.c view.c + PORTDNSSRCS = ecdb.c ++GEOIPLINKSRCS = geoip.c + +-SRCS = ${DSTSRCS} ${DNSSRCS} ${PORTDNSSRCS} ++SRCS = ${DSTSRCS} ${DNSSRCS} ${PORTDNSSRCS} @GEOIPLINKSRCS@ + + SUBDIRS = include + TARGETS = include/dns/enumtype.h include/dns/enumclass.h \ +diff --git a/lib/isccfg/aclconf.c b/lib/isccfg/aclconf.c +index af56599..c415a98 100644 +--- a/lib/isccfg/aclconf.c ++++ b/lib/isccfg/aclconf.c +@@ -31,6 +31,11 @@ + #include + #include + ++#ifdef HAVE_GEOIP ++#include ++#include ++#endif /* HAVE_GEOIP */ ++ + #define LOOP_MAGIC ISC_MAGIC('L','O','O','P') + + isc_result_t +@@ -53,6 +58,10 @@ cfg_aclconfctx_create(isc_mem_t *mctx, cfg_aclconfctx_t **ret) { + isc_mem_attach(mctx, &actx->mctx); + ISC_LIST_INIT(actx->named_acl_cache); + ++#ifdef HAVE_GEOIP ++ actx->geoip = NULL; ++#endif ++ + *ret = actx; + return (ISC_R_SUCCESS); + +@@ -230,11 +239,15 @@ count_acl_elements(const cfg_obj_t *caml, const cfg_obj_t *cctx, + elt = cfg_list_next(elt)) { + const cfg_obj_t *ce = cfg_listelt_value(elt); + +- /* negated element; just get the value. */ ++ /* might be a negated element, in which case get the value. */ + if (cfg_obj_istuple(ce)) { +- ce = cfg_tuple_get(ce, "value"); +- if (has_negative != NULL) +- *has_negative = ISC_TRUE; ++ const cfg_obj_t *negated = ++ cfg_tuple_get(ce, "negated"); ++ if (! cfg_obj_isvoid(negated)) { ++ ce = negated; ++ if (has_negative != NULL) ++ *has_negative = ISC_TRUE; ++ } + } + + if (cfg_obj_istype(ce, &cfg_type_keyref)) { +@@ -244,6 +257,12 @@ count_acl_elements(const cfg_obj_t *caml, const cfg_obj_t *cctx, + n += count_acl_elements(ce, cctx, &negative); + if (negative) + n++; ++#ifdef HAVE_GEOIP ++ } else if (cfg_obj_istuple(ce) && ++ cfg_obj_isvoid(cfg_tuple_get(ce, "negated"))) ++ { ++ n++; ++#endif /* HAVE_GEOIP */ + } else if (cfg_obj_isstring(ce)) { + const char *name = cfg_obj_asstring(ce); + if (strcasecmp(name, "localhost") == 0 || +@@ -262,6 +281,313 @@ count_acl_elements(const cfg_obj_t *caml, const cfg_obj_t *cctx, + return n; + } + ++#ifdef HAVE_GEOIP ++static dns_geoip_subtype_t ++get_subtype(const cfg_obj_t *obj, isc_log_t *lctx, ++ dns_geoip_subtype_t subtype, const char *dbname) ++{ ++ if (dbname == NULL) ++ return (subtype); ++ ++ switch (subtype) { ++ case dns_geoip_countrycode: ++ if (strcasecmp(dbname, "city") == 0) ++ return (dns_geoip_city_countrycode); ++ else if (strcasecmp(dbname, "region") == 0) ++ return (dns_geoip_region_countrycode); ++ else if (strcasecmp(dbname, "country") == 0) ++ return (dns_geoip_country_code); ++ cfg_obj_log(obj, lctx, ISC_LOG_ERROR, ++ "invalid GeoIP DB specified for " ++ "country search: ignored"); ++ return (subtype); ++ case dns_geoip_countrycode3: ++ if (strcasecmp(dbname, "city") == 0) ++ return (dns_geoip_city_countrycode3); ++ else if (strcasecmp(dbname, "country") == 0) ++ return (dns_geoip_country_code3); ++ cfg_obj_log(obj, lctx, ISC_LOG_ERROR, ++ "invalid GeoIP DB specified for " ++ "country search: ignored"); ++ return (subtype); ++ case dns_geoip_countryname: ++ if (strcasecmp(dbname, "city") == 0) ++ return (dns_geoip_city_countryname); ++ else if (strcasecmp(dbname, "country") == 0) ++ return (dns_geoip_country_name); ++ cfg_obj_log(obj, lctx, ISC_LOG_ERROR, ++ "invalid GeoIP DB specified for " ++ "country search: ignored"); ++ return (subtype); ++ case dns_geoip_region: ++ if (strcasecmp(dbname, "city") == 0) ++ return (dns_geoip_city_region); ++ else if (strcasecmp(dbname, "region") == 0) ++ return (dns_geoip_region_code); ++ cfg_obj_log(obj, lctx, ISC_LOG_ERROR, ++ "invalid GeoIP DB specified for " ++ "region search: ignored"); ++ return (subtype); ++ case dns_geoip_regionname: ++ if (strcasecmp(dbname, "city") == 0) ++ return (dns_geoip_city_region); ++ else if (strcasecmp(dbname, "region") == 0) ++ return (dns_geoip_region_name); ++ cfg_obj_log(obj, lctx, ISC_LOG_ERROR, ++ "invalid GeoIP DB specified for " ++ "region search: ignored"); ++ return (subtype); ++ ++ /* ++ * Log a warning if the wrong database was specified ++ * on an unambiguous query ++ */ ++ case dns_geoip_city_name: ++ case dns_geoip_city_postalcode: ++ case dns_geoip_city_metrocode: ++ case dns_geoip_city_areacode: ++ case dns_geoip_city_continentcode: ++ case dns_geoip_city_timezonecode: ++ if (strcasecmp(dbname, "city") != 0) ++ cfg_obj_log(obj, lctx, ISC_LOG_WARNING, ++ "invalid GeoIP DB specified for " ++ "a 'city'-only search type: ignoring"); ++ return (subtype); ++ case dns_geoip_isp_name: ++ if (strcasecmp(dbname, "isp") != 0) ++ cfg_obj_log(obj, lctx, ISC_LOG_WARNING, ++ "invalid GeoIP DB specified for " ++ "an 'isp' search: ignoring"); ++ return (subtype); ++ case dns_geoip_org_name: ++ if (strcasecmp(dbname, "org") != 0) ++ cfg_obj_log(obj, lctx, ISC_LOG_WARNING, ++ "invalid GeoIP DB specified for " ++ "an 'org' search: ignoring"); ++ return (subtype); ++ case dns_geoip_as_asnum: ++ if (strcasecmp(dbname, "asnum") != 0) ++ cfg_obj_log(obj, lctx, ISC_LOG_WARNING, ++ "invalid GeoIP DB specified for " ++ "an 'asnum' search: ignoring"); ++ return (subtype); ++ case dns_geoip_domain_name: ++ if (strcasecmp(dbname, "domain") != 0) ++ cfg_obj_log(obj, lctx, ISC_LOG_WARNING, ++ "invalid GeoIP DB specified for " ++ "a 'domain' search: ignoring"); ++ return (subtype); ++ case dns_geoip_netspeed_id: ++ if (strcasecmp(dbname, "netspeed") != 0) ++ cfg_obj_log(obj, lctx, ISC_LOG_WARNING, ++ "invalid GeoIP DB specified for " ++ "a 'netspeed' search: ignoring"); ++ return (subtype); ++ default: ++ INSIST(0); ++ } ++} ++ ++static isc_boolean_t ++geoip_can_answer(dns_aclelement_t *elt, cfg_aclconfctx_t *ctx) { ++ if (ctx->geoip == NULL) ++ return (ISC_TRUE); ++ ++ switch (elt->geoip_elem.subtype) { ++ case dns_geoip_countrycode: ++ case dns_geoip_countrycode3: ++ case dns_geoip_countryname: ++ if (ctx->geoip->city_v4 != NULL || ++ ctx->geoip->city_v6 != NULL || ++ ctx->geoip->country_v4 != NULL || ++ ctx->geoip->country_v6 != NULL || ++ ctx->geoip->region != NULL) ++ return (ISC_TRUE); ++ case dns_geoip_region: ++ case dns_geoip_regionname: ++ if (ctx->geoip->city_v4 != NULL || ++ ctx->geoip->city_v6 != NULL || ++ ctx->geoip->region != NULL) ++ return (ISC_TRUE); ++ case dns_geoip_country_code: ++ case dns_geoip_country_code3: ++ case dns_geoip_country_name: ++ if (ctx->geoip->country_v4 != NULL || ++ ctx->geoip->country_v6 != NULL) ++ return (ISC_TRUE); ++ case dns_geoip_region_countrycode: ++ case dns_geoip_region_code: ++ case dns_geoip_region_name: ++ if (ctx->geoip->region != NULL) ++ return (ISC_TRUE); ++ 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_metrocode: ++ case dns_geoip_city_areacode: ++ case dns_geoip_city_continentcode: ++ case dns_geoip_city_timezonecode: ++ if (ctx->geoip->city_v4 != NULL || ++ ctx->geoip->city_v6 != NULL) ++ return (ISC_TRUE); ++ case dns_geoip_isp_name: ++ if (ctx->geoip->isp != NULL) ++ return (ISC_TRUE); ++ case dns_geoip_org_name: ++ if (ctx->geoip->org != NULL) ++ return (ISC_TRUE); ++ case dns_geoip_as_asnum: ++ if (ctx->geoip->as != NULL) ++ return (ISC_TRUE); ++ case dns_geoip_domain_name: ++ if (ctx->geoip->domain != NULL) ++ return (ISC_TRUE); ++ case dns_geoip_netspeed_id: ++ if (ctx->geoip->netspeed != NULL) ++ return (ISC_TRUE); ++ } ++ ++ return (ISC_FALSE); ++} ++ ++static isc_result_t ++parse_geoip_element(const cfg_obj_t *obj, isc_log_t *lctx, ++ cfg_aclconfctx_t *ctx, dns_aclelement_t *dep) ++{ ++ const cfg_obj_t *ge; ++ const char *dbname = NULL; ++ const char *stype, *search; ++ dns_geoip_subtype_t subtype; ++ dns_aclelement_t de; ++ size_t len; ++ ++ REQUIRE(dep != NULL); ++ ++ de = *dep; ++ ++ ge = cfg_tuple_get(obj, "db"); ++ if (!cfg_obj_isvoid(ge)) ++ dbname = cfg_obj_asstring(ge); ++ ++ stype = cfg_obj_asstring(cfg_tuple_get(obj, "subtype")); ++ search = cfg_obj_asstring(cfg_tuple_get(obj, "search")); ++ len = strlen(search); ++ ++ if (len == 0) { ++ cfg_obj_log(obj, lctx, ISC_LOG_ERROR, ++ "zero-length geoip search field"); ++ return (ISC_R_FAILURE); ++ } ++ ++ if (strcasecmp(stype, "country") == 0 && len == 2) { ++ /* Two-letter country code */ ++ subtype = dns_geoip_countrycode; ++ strlcpy(de.geoip_elem.as_string, search, ++ sizeof(de.geoip_elem.as_string)); ++ } else if (strcasecmp(stype, "country") == 0 && len == 3) { ++ /* Three-letter country code */ ++ subtype = dns_geoip_countrycode3; ++ strlcpy(de.geoip_elem.as_string, search, ++ sizeof(de.geoip_elem.as_string)); ++ } else if (strcasecmp(stype, "country") == 0) { ++ /* Country name */ ++ subtype = dns_geoip_countryname; ++ strlcpy(de.geoip_elem.as_string, search, ++ sizeof(de.geoip_elem.as_string)); ++ } else if (strcasecmp(stype, "region") == 0 && len == 2) { ++ /* Two-letter region code */ ++ subtype = dns_geoip_region; ++ strlcpy(de.geoip_elem.as_string, search, ++ sizeof(de.geoip_elem.as_string)); ++ } else if (strcasecmp(stype, "region") == 0) { ++ /* Region name */ ++ subtype = dns_geoip_regionname; ++ strlcpy(de.geoip_elem.as_string, search, ++ sizeof(de.geoip_elem.as_string)); ++ } else if (strcasecmp(stype, "city") == 0) { ++ /* City name */ ++ subtype = dns_geoip_city_name; ++ strlcpy(de.geoip_elem.as_string, search, ++ sizeof(de.geoip_elem.as_string)); ++ } else if (strcasecmp(stype, "postal") == 0 || ++ strcasecmp(stype, "postalcode") == 0) ++ { ++ if (len < 7) { ++ subtype = dns_geoip_city_postalcode; ++ strlcpy(de.geoip_elem.as_string, search, ++ sizeof(de.geoip_elem.as_string)); ++ } else { ++ cfg_obj_log(obj, lctx, ISC_LOG_ERROR, ++ "geoiop postal code (%s) too long", ++ search); ++ return (ISC_R_FAILURE); ++ } ++ } else if (strcasecmp(stype, "metro") == 0 || ++ strcasecmp(stype, "metrocode") == 0) ++ { ++ subtype = dns_geoip_city_metrocode; ++ de.geoip_elem.as_int = atoi(search); ++ } else if (strcasecmp(stype, "area") == 0 || ++ strcasecmp(stype, "areacode") == 0) ++ { ++ subtype = dns_geoip_city_areacode; ++ de.geoip_elem.as_int = atoi(search); ++ } else if (strcasecmp(stype, "tz") == 0 || ++ strcasecmp(stype, "timezone") == 0) ++ { ++ subtype = dns_geoip_city_timezonecode; ++ strlcpy(de.geoip_elem.as_string, search, ++ sizeof(de.geoip_elem.as_string)); ++ } else if (strcasecmp(stype, "continent") == 0 && len == 2) { ++ /* Two-letter continent code */ ++ subtype = dns_geoip_city_continentcode; ++ strlcpy(de.geoip_elem.as_string, search, ++ sizeof(de.geoip_elem.as_string)); ++ } else if (strcasecmp(stype, "continent") == 0) { ++ cfg_obj_log(obj, lctx, ISC_LOG_ERROR, ++ "geoiop continent code (%s) too long", search); ++ return (ISC_R_FAILURE); ++ } else if (strcasecmp(stype, "isp") == 0) { ++ subtype = dns_geoip_isp_name; ++ strlcpy(de.geoip_elem.as_string, search, ++ sizeof(de.geoip_elem.as_string)); ++ } else if (strcasecmp(stype, "asnum") == 0) { ++ subtype = dns_geoip_as_asnum; ++ strlcpy(de.geoip_elem.as_string, search, ++ sizeof(de.geoip_elem.as_string)); ++ } else if (strcasecmp(stype, "org") == 0) { ++ subtype = dns_geoip_org_name; ++ strlcpy(de.geoip_elem.as_string, search, ++ sizeof(de.geoip_elem.as_string)); ++ } else if (strcasecmp(stype, "domain") == 0) { ++ subtype = dns_geoip_domain_name; ++ strlcpy(de.geoip_elem.as_string, search, ++ sizeof(de.geoip_elem.as_string)); ++ } else if (strcasecmp(stype, "netspeed") == 0) { ++ subtype = dns_geoip_netspeed_id; ++ de.geoip_elem.as_int = atoi(search); ++ } else ++ INSIST(0); ++ ++ de.geoip_elem.subtype = get_subtype(obj, lctx, subtype, dbname); ++ ++ if (! geoip_can_answer(&de, ctx)) { ++ cfg_obj_log(obj, lctx, ISC_LOG_ERROR, ++ "no GeoIP database installed which can answer " ++ "queries of type '%s'", stype); ++ return (ISC_R_FAILURE); ++ } ++ ++ *dep = de; ++ ++ return (ISC_R_SUCCESS); ++} ++#endif ++ + isc_result_t + cfg_acl_fromconfig(const cfg_obj_t *caml, + const cfg_obj_t *cctx, +@@ -317,15 +643,18 @@ cfg_acl_fromconfig(const cfg_obj_t *caml, + elt != NULL; + elt = cfg_list_next(elt)) { + const cfg_obj_t *ce = cfg_listelt_value(elt); +- isc_boolean_t neg; ++ isc_boolean_t neg = ISC_FALSE; + + if (cfg_obj_istuple(ce)) { +- /* This must be a negated element. */ +- ce = cfg_tuple_get(ce, "value"); +- neg = ISC_TRUE; +- dacl->has_negatives = ISC_TRUE; +- } else +- neg = ISC_FALSE; ++ /* Might be a negated element */ ++ const cfg_obj_t *negated = ++ cfg_tuple_get(ce, "negated"); ++ if (! cfg_obj_isvoid(negated)) { ++ neg = ISC_TRUE; ++ dacl->has_negatives = ISC_TRUE; ++ ce = negated; ++ } ++ } + + /* + * If nest_level is nonzero, then every element is +@@ -405,6 +734,16 @@ nested_acl: + &de->keyname); + if (result != ISC_R_SUCCESS) + goto cleanup; ++#ifdef HAVE_GEOIP ++ } else if (cfg_obj_istuple(ce) && ++ cfg_obj_isvoid(cfg_tuple_get(ce, "negated"))) ++ { ++ result = parse_geoip_element(ce, lctx, ctx, de); ++ if (result != ISC_R_SUCCESS) ++ goto cleanup; ++ de->type = dns_aclelementtype_geoip; ++ de->negative = neg; ++#endif /* HAVE_GEOIP */ + } else if (cfg_obj_isstring(ce)) { + /* ACL name. */ + const char *name = cfg_obj_asstring(ce); +diff --git a/lib/isccfg/include/isccfg/aclconf.h b/lib/isccfg/include/isccfg/aclconf.h +index 38ab9f6..3fb66f9 100644 +--- a/lib/isccfg/include/isccfg/aclconf.h ++++ b/lib/isccfg/include/isccfg/aclconf.h +@@ -24,11 +24,17 @@ + + #include + ++#ifdef HAVE_GEOIP ++#include ++#endif + #include + + typedef struct cfg_aclconfctx { + ISC_LIST(dns_acl_t) named_acl_cache; + isc_mem_t *mctx; ++#ifdef HAVE_GEOIP ++ dns_geoip_databases_t *geoip; ++#endif + isc_refcount_t references; + } cfg_aclconfctx_t; + +diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c +index acaef2b..f5ff8e3 100644 +--- a/lib/isccfg/namedconf.c ++++ b/lib/isccfg/namedconf.c +@@ -82,6 +82,17 @@ doc_keyvalue(cfg_printer_t *pctx, const cfg_type_t *type); + static void + doc_optional_keyvalue(cfg_printer_t *pctx, const cfg_type_t *type); + ++#ifdef HAVE_GEOIP ++static isc_result_t ++parse_geoip(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); ++ ++static void ++print_geoip(cfg_printer_t *pctx, const cfg_obj_t *obj); ++ ++static void ++doc_geoip(cfg_printer_t *pctx, const cfg_type_t *type); ++#endif /* HAVE_GEOIP */ ++ + static cfg_type_t cfg_type_acl; + static cfg_type_t cfg_type_addrmatchelt; + static cfg_type_t cfg_type_bracketed_aml; +@@ -935,6 +946,9 @@ options_clauses[] = { + { "fake-iquery", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, + { "files", &cfg_type_size, 0 }, + { "flush-zones-on-shutdown", &cfg_type_boolean, 0 }, ++#ifdef HAVE_GEOIP ++ { "geoip-directory", &cfg_type_qstringornone, 0 }, ++#endif /* HAVE_GEOIP */ + { "has-old-clients", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, + { "heartbeat-interval", &cfg_type_uint32, 0 }, + { "host-statistics", &cfg_type_boolean, CFG_CLAUSEFLAG_NOTIMP }, +@@ -2126,6 +2140,102 @@ static cfg_type_t cfg_type_optional_keyref = { + doc_optional_keyvalue, &cfg_rep_string, &key_kw + }; + ++#ifdef HAVE_GEOIP ++/* ++ * "geoip" ACL element: ++ * geoip [ db ] search-type ++ */ ++static const char *geoiptype_enums[] = { ++ "country", "country3", "countryname", "region", "regionname", ++ "city", "postalcode", "postal", "metrocode", "metro", ++ "areacode", "area", "timezone", "tz", "continent", "isp", ++ "domain", "asnum", "org", "netspeed", NULL ++}; ++static cfg_type_t cfg_type_geoiptype = { ++ "geoiptype", cfg_parse_enum, cfg_print_ustring, ++ cfg_doc_enum, &cfg_rep_string, &geoiptype_enums ++}; ++ ++static const char *geoipdb_enums[] = { ++ "country", "region", "city", ++ "isp", "domain", "asnum", "org", "netspeed", NULL ++}; ++static cfg_type_t cfg_type_geoipdb = { ++ "geoipdb", cfg_parse_enum, cfg_print_ustring, ++ cfg_doc_enum, &cfg_rep_string, &geoipdb_enums ++}; ++ ++static cfg_tuplefielddef_t geoip_fields[] = { ++ { "negated", &cfg_type_void, 0}, ++ { "db", &cfg_type_geoipdb, 0}, ++ { "subtype", &cfg_type_geoiptype, 0 }, ++ { "search", &cfg_type_astring, 0 }, ++ { NULL, NULL, 0 } ++}; ++ ++static cfg_type_t cfg_type_geoip = { ++ "geoip", parse_geoip, print_geoip, doc_geoip, ++ &cfg_rep_tuple, geoip_fields ++}; ++ ++static isc_result_t ++parse_geoip(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { ++ isc_result_t result; ++ cfg_obj_t *obj = NULL; ++ const cfg_tuplefielddef_t *fields = type->of; ++ ++ CHECK(cfg_create_tuple(pctx, type, &obj)); ++ CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[0])); ++ ++ /* Parse the optional "db" field. */ ++ CHECK(cfg_peektoken(pctx, 0)); ++ if (pctx->token.type == isc_tokentype_string) { ++ CHECK(cfg_gettoken(pctx, 0)); ++ if (strcasecmp(TOKEN_STRING(pctx), "db") == 0 && ++ obj->value.tuple[1] == NULL) { ++ CHECK(cfg_parse_obj(pctx, fields[1].type, ++ &obj->value.tuple[1])); ++ } else { ++ CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[1])); ++ cfg_ungettoken(pctx); ++ } ++ } ++ ++ CHECK(cfg_parse_obj(pctx, fields[2].type, &obj->value.tuple[2])); ++ CHECK(cfg_parse_obj(pctx, fields[3].type, &obj->value.tuple[3])); ++ ++ *ret = obj; ++ return (ISC_R_SUCCESS); ++ ++ cleanup: ++ CLEANUP_OBJ(obj); ++ return (result); ++} ++ ++static void ++print_geoip(cfg_printer_t *pctx, const cfg_obj_t *obj) { ++ if (obj->value.tuple[1]->type->print != cfg_print_void) { ++ cfg_print_cstr(pctx, " db "); ++ cfg_print_obj(pctx, obj->value.tuple[1]); ++ } ++ cfg_print_obj(pctx, obj->value.tuple[2]); ++ cfg_print_obj(pctx, obj->value.tuple[3]); ++} ++ ++ ++static void ++doc_geoip(cfg_printer_t *pctx, const cfg_type_t *type) { ++ UNUSED(type); ++ cfg_print_cstr(pctx, "[ db "); ++ cfg_doc_enum(pctx, &cfg_type_geoipdb); ++ cfg_print_cstr(pctx, " ]"); ++ cfg_print_chars(pctx, " ", 1); ++ cfg_doc_enum(pctx, &cfg_type_geoiptype); ++ cfg_print_chars(pctx, " ", 1); ++ cfg_print_cstr(pctx, ""); ++} ++#endif /* HAVE_GEOIP */ ++ + /*% + * A "controls" statement is represented as a map with the multivalued + * "inet" and "unix" clauses. +@@ -2269,7 +2379,9 @@ static cfg_type_t cfg_type_statschannels = { + * An optional class, as used in view and zone statements. + */ + static isc_result_t +-parse_optional_class(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { ++parse_optional_class(cfg_parser_t *pctx, const cfg_type_t *type, ++ cfg_obj_t **ret) ++{ + isc_result_t result; + UNUSED(type); + CHECK(cfg_peektoken(pctx, 0)); +@@ -2392,6 +2504,16 @@ parse_addrmatchelt(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) + if (pctx->token.type == isc_tokentype_string && + (strcasecmp(TOKEN_STRING(pctx), "key") == 0)) { + CHECK(cfg_parse_obj(pctx, &cfg_type_keyref, ret)); ++ } else if (pctx->token.type == isc_tokentype_string && ++ (strcasecmp(TOKEN_STRING(pctx), "geoip") == 0)) { ++#ifdef HAVE_GEOIP ++ CHECK(cfg_gettoken(pctx, 0)); ++ CHECK(cfg_parse_obj(pctx, &cfg_type_geoip, ret)); ++#else ++ cfg_parser_error(pctx, CFG_LOG_NEAR, ++ "'geoip' not supported in this build"); ++ return (ISC_R_UNEXPECTEDTOKEN); ++#endif + } else { + if (cfg_lookingat_netaddr(pctx, CFG_ADDR_V4OK | + CFG_ADDR_V4PREFIXOK | +@@ -2405,7 +2527,8 @@ parse_addrmatchelt(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) + } else if (pctx->token.type == isc_tokentype_special) { + if (pctx->token.value.as_char == '{') { + /* Nested match list. */ +- CHECK(cfg_parse_obj(pctx, &cfg_type_bracketed_aml, ret)); ++ CHECK(cfg_parse_obj(pctx, ++ &cfg_type_bracketed_aml, ret)); + } else if (pctx->token.value.as_char == '!') { + CHECK(cfg_gettoken(pctx, 0)); /* read "!" */ + CHECK(cfg_parse_obj(pctx, &cfg_type_negated, ret)); +@@ -2429,7 +2552,7 @@ parse_addrmatchelt(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) + */ + + static cfg_tuplefielddef_t negated_fields[] = { +- { "value", &cfg_type_addrmatchelt, 0 }, ++ { "negated", &cfg_type_addrmatchelt, 0 }, + { NULL, NULL, 0 } + }; + +-- +2.5.5 + diff --git a/SOURCES/bind99-rh1259514.patch b/SOURCES/bind99-rh1259514.patch new file mode 100644 index 0000000..3b268d0 --- /dev/null +++ b/SOURCES/bind99-rh1259514.patch @@ -0,0 +1,12 @@ +diff --git a/bin/tests/system/tkey/ns1/named.conf.in b/bin/tests/system/tkey/ns1/named.conf.in +index 50600b7..b0f1700 100644 +--- a/bin/tests/system/tkey/ns1/named.conf.in ++++ b/bin/tests/system/tkey/ns1/named.conf.in +@@ -32,6 +32,7 @@ options { + tkey-domain "server"; + tkey-dhkey "server" KEYID; + allow-query-cache { any; }; ++ random-device "/dev/urandom"; + }; + + key rndc_key { diff --git a/SOURCES/bind99-rh1291185.patch b/SOURCES/bind99-rh1291185.patch new file mode 100644 index 0000000..9f7c936 --- /dev/null +++ b/SOURCES/bind99-rh1291185.patch @@ -0,0 +1,58 @@ +diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c +index 8696b15..5ef2dd6 100644 +--- a/lib/dns/resolver.c ++++ b/lib/dns/resolver.c +@@ -7373,9 +7373,12 @@ resquery_response(isc_task_t *task, isc_event_t *event) { + * NXDOMAIN, NXRDATASET, or referral. + */ + result = noanswer_response(fctx, NULL, 0); +- if (result == DNS_R_CHASEDSSERVERS) { +- } else if (result == DNS_R_DELEGATION) { +- force_referral: ++ 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. +@@ -7400,7 +7403,8 @@ resquery_response(isc_task_t *task, isc_event_t *event) { + fctx->adberr = 0; + + result = ISC_R_SUCCESS; +- } else if (result != ISC_R_SUCCESS) { ++ break; ++ default: + /* + * Something has gone wrong. + */ +diff --git a/lib/dns/view.c b/lib/dns/view.c +index 142b09e..35900b3 100644 +--- a/lib/dns/view.c ++++ b/lib/dns/view.c +@@ -1216,6 +1216,7 @@ dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname, + dns_name_t *zfname; + dns_rdataset_t zrdataset, zsigrdataset; + dns_fixedname_t zfixedname; ++ unsigned int ztoptions = 0; + + #ifndef BIND9 + UNUSED(zone); +@@ -1242,9 +1243,12 @@ dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname, + #ifdef BIND9 + zone = NULL; + LOCK(&view->lock); +- if (view->zonetable != NULL) +- result = dns_zt_find(view->zonetable, name, 0, NULL, &zone); +- else ++ if (view->zonetable != NULL) { ++ if ((options & DNS_DBFIND_NOEXACT) != 0) ++ ztoptions |= DNS_ZTFIND_NOEXACT; ++ result = dns_zt_find(view->zonetable, name, ztoptions, ++ NULL, &zone); ++ } else + result = ISC_R_NOTFOUND; + if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) + result = dns_zone_getdb(zone, &db); diff --git a/SOURCES/bind99-rh1306610.patch b/SOURCES/bind99-rh1306610.patch new file mode 100644 index 0000000..cf5c8cc --- /dev/null +++ b/SOURCES/bind99-rh1306610.patch @@ -0,0 +1,1847 @@ +From 620b1c9d90d0a59a0d892fef089ce4f5f6f61742 Mon Sep 17 00:00:00 2001 +From: Tomas Hozza +Date: Fri, 1 Apr 2016 15:20:27 +0200 +Subject: [PATCH] Added support for CAA records + +Signed-off-by: Tomas Hozza +--- + bin/tests/rdata_test.c | 17 +- + doc/rfc/rfc6844.txt | 1011 ++++++++++++++++++++++++++++++++++++++ + lib/dns/rdata.c | 95 ++-- + lib/dns/rdata/generic/caa_257.c | 370 ++++++++++++++ + lib/dns/rdata/generic/caa_257.h | 32 ++ + lib/dns/rdata/generic/gpos_27.c | 2 +- + lib/dns/rdata/generic/hinfo_13.c | 4 +- + lib/dns/rdata/generic/isdn_20.c | 4 +- + lib/dns/rdata/generic/naptr_35.c | 6 +- + lib/dns/rdata/generic/spf_99.c | 2 +- + lib/dns/rdata/generic/txt_16.c | 2 +- + lib/dns/rdata/generic/uri_256.c | 23 +- + lib/dns/rdata/generic/x25_19.c | 2 +- + 13 files changed, 1478 insertions(+), 92 deletions(-) + create mode 100644 doc/rfc/rfc6844.txt + create mode 100644 lib/dns/rdata/generic/caa_257.c + create mode 100644 lib/dns/rdata/generic/caa_257.h + +diff --git a/bin/tests/rdata_test.c b/bin/tests/rdata_test.c +index 51cc406..0f25364 100644 +--- a/bin/tests/rdata_test.c ++++ b/bin/tests/rdata_test.c +@@ -15,8 +15,6 @@ + * PERFORMANCE OF THIS SOFTWARE. + */ + +-/* $Id: rdata_test.c,v 1.52 2011/08/28 09:10:41 marka Exp $ */ +- + #include + + #include +@@ -284,6 +282,11 @@ viastruct(dns_rdata_t *rdata, isc_mem_t *mctx, + result = dns_rdata_tostruct(rdata, sp = &uri, NULL); + break; + } ++ case dns_rdatatype_caa: { ++ static dns_rdata_caa_t caa; ++ result = dns_rdata_tostruct(rdata, sp = &caa, NULL); ++ break; ++ } + case dns_rdatatype_wks: { + static dns_rdata_in_wks_t in_wks; + result = dns_rdata_tostruct(rdata, sp = &in_wks, NULL); +@@ -551,6 +554,11 @@ viastruct(dns_rdata_t *rdata, isc_mem_t *mctx, + result = dns_rdata_tostruct(rdata, sp = &uri, mctx); + break; + } ++ case dns_rdatatype_caa: { ++ static dns_rdata_caa_t caa; ++ result = dns_rdata_tostruct(rdata, sp = &caa, mctx); ++ break; ++ } + case dns_rdatatype_wks: { + static dns_rdata_in_wks_t in_wks; + result = dns_rdata_tostruct(rdata, sp = &in_wks, mctx); +@@ -848,6 +856,11 @@ viastruct(dns_rdata_t *rdata, isc_mem_t *mctx, + result = dns_rdata_fromstruct(rdata2, rdc, rdt, &uri, b); + break; + } ++ case dns_rdatatype_caa: { ++ dns_rdata_caa_t caa; ++ result = dns_rdata_fromstruct(rdata2, rdc, rdt, &caa, b); ++ break; ++ } + case dns_rdatatype_wks: { + dns_rdata_in_wks_t in_wks; + result = dns_rdata_fromstruct(rdata2, rdc, rdt, &in_wks, b); +diff --git a/doc/rfc/rfc6844.txt b/doc/rfc/rfc6844.txt +new file mode 100644 +index 0000000..d923649 +--- /dev/null ++++ b/doc/rfc/rfc6844.txt +@@ -0,0 +1,1011 @@ ++ ++ ++ ++ ++ ++ ++Internet Engineering Task Force (IETF) P. Hallam-Baker ++Request for Comments: 6844 Comodo Group, Inc. ++Category: Standards Track R. Stradling ++ISSN: 2070-1721 Comodo CA, Ltd. ++ January 2013 ++ ++ ++ DNS Certification Authority Authorization (CAA) Resource Record ++ ++Abstract ++ ++ The Certification Authority Authorization (CAA) DNS Resource Record ++ allows a DNS domain name holder to specify one or more Certification ++ Authorities (CAs) authorized to issue certificates for that domain. ++ CAA Resource Records allow a public Certification Authority to ++ implement additional controls to reduce the risk of unintended ++ certificate mis-issue. This document defines the syntax of the CAA ++ record and rules for processing CAA records by certificate issuers. ++ ++Status of This Memo ++ ++ This is an Internet Standards Track document. ++ ++ This document is a product of the Internet Engineering Task Force ++ (IETF). It represents the consensus of the IETF community. It has ++ received public review and has been approved for publication by the ++ Internet Engineering Steering Group (IESG). Further information on ++ Internet Standards is available in Section 2 of RFC 5741. ++ ++ Information about the current status of this document, any errata, ++ and how to provide feedback on it may be obtained at ++ http://www.rfc-editor.org/info/rfc6844. ++ ++Copyright Notice ++ ++ Copyright (c) 2013 IETF Trust and the persons identified as the ++ document authors. All rights reserved. ++ ++ This document is subject to BCP 78 and the IETF Trust's Legal ++ Provisions Relating to IETF Documents ++ (http://trustee.ietf.org/license-info) in effect on the date of ++ publication of this document. Please review these documents ++ carefully, as they describe your rights and restrictions with respect ++ to this document. Code Components extracted from this document must ++ include Simplified BSD License text as described in Section 4.e of ++ the Trust Legal Provisions and are provided without warranty as ++ described in the Simplified BSD License. ++ ++ ++ ++ ++Hallam-Baker & Stradling Standards Track [Page 1] ++ ++RFC 6844 Certification Authority Authorization January 2013 ++ ++ ++Table of Contents ++ ++ 1. Introduction ....................................................2 ++ 2. Definitions .....................................................3 ++ 2.1. Requirements Language ......................................3 ++ 2.2. Defined Terms ..............................................3 ++ 3. The CAA RR Type .................................................5 ++ 4. Certification Authority Processing ..............................7 ++ 4.1. Use of DNS Security ........................................8 ++ 5. Mechanism .......................................................8 ++ 5.1. Syntax .....................................................8 ++ 5.1.1. Canonical Presentation Format ......................10 ++ 5.2. CAA issue Property ........................................10 ++ 5.3. CAA issuewild Property ....................................12 ++ 5.4. CAA iodef Property ........................................12 ++ 6. Security Considerations ........................................13 ++ 6.1. Non-Compliance by Certification Authority .................13 ++ 6.2. Mis-Issue by Authorized Certification Authority ...........13 ++ 6.3. Suppression or Spoofing of CAA Records ....................13 ++ 6.4. Denial of Service .........................................14 ++ 6.5. Abuse of the Critical Flag ................................14 ++ 7. IANA Considerations ............................................14 ++ 7.1. Registration of the CAA Resource Record Type ..............14 ++ 7.2. Certification Authority Restriction Properties ............15 ++ 7.3. Certification Authority Restriction Flags .................15 ++ 8. Acknowledgements ...............................................16 ++ 9. References .....................................................16 ++ 9.1. Normative References ......................................16 ++ 9.2. Informative References ....................................17 ++ ++1. Introduction ++ ++ The Certification Authority Authorization (CAA) DNS Resource Record ++ allows a DNS domain name holder to specify the Certification ++ Authorities (CAs) authorized to issue certificates for that domain. ++ Publication of CAA Resource Records allows a public Certification ++ Authority to implement additional controls to reduce the risk of ++ unintended certificate mis-issue. ++ ++ Like the TLSA record defined in DNS-Based Authentication of Named ++ Entities (DANE) [RFC6698], CAA records are used as a part of a ++ mechanism for checking PKIX certificate data. The distinction ++ between the two specifications is that CAA records specify an ++ authorization control to be performed by a certificate issuer before ++ issue of a certificate and TLSA records specify a verification ++ control to be performed by a relying party after the certificate is ++ issued. ++ ++ ++ ++ ++Hallam-Baker & Stradling Standards Track [Page 2] ++ ++RFC 6844 Certification Authority Authorization January 2013 ++ ++ ++ Conformance with a published CAA record is a necessary but not ++ sufficient condition for issuance of a certificate. Before issuing a ++ certificate, a PKIX CA is required to validate the request according ++ to the policies set out in its Certificate Policy. In the case of a ++ public CA that validates certificate requests as a third party, the ++ certificate will typically be issued under a public trust anchor ++ certificate embedded in one or more relevant Relying Applications. ++ ++ Criteria for inclusion of embedded trust anchor certificates in ++ applications are outside the scope of this document. Typically, such ++ criteria require the CA to publish a Certificate Practices Statement ++ (CPS) that specifies how the requirements of the Certificate Policy ++ (CP) are achieved. It is also common for a CA to engage an ++ independent third-party auditor to prepare an annual audit statement ++ of its performance against its CPS. ++ ++ A set of CAA records describes only current grants of authority to ++ issue certificates for the corresponding DNS domain. Since a ++ certificate is typically valid for at least a year, it is possible ++ that a certificate that is not conformant with the CAA records ++ currently published was conformant with the CAA records published at ++ the time that the certificate was issued. Relying Applications MUST ++ NOT use CAA records as part of certificate validation. ++ ++ CAA records MAY be used by Certificate Evaluators as a possible ++ indicator of a security policy violation. Such use SHOULD take ++ account of the possibility that published CAA records changed between ++ the time a certificate was issued and the time at which the ++ certificate was observed by the Certificate Evaluator. ++ ++2. Definitions ++ ++2.1. Requirements Language ++ ++ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", ++ "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this ++ document are to be interpreted as described in [RFC2119]. ++ ++2.2. Defined Terms ++ ++ The following terms are used in this document: ++ ++ Authorization Entry: An authorization assertion that grants or ++ denies a specific set of permissions to a specific group of ++ entities. ++ ++ Certificate: An X.509 Certificate, as specified in [RFC5280]. ++ ++ ++ ++ ++Hallam-Baker & Stradling Standards Track [Page 3] ++ ++RFC 6844 Certification Authority Authorization January 2013 ++ ++ ++ Certificate Evaluator: A party other than a relying party that ++ evaluates the trustworthiness of certificates issued by ++ Certification Authorities. ++ ++ Certification Authority (CA): An issuer that issues certificates in ++ accordance with a specified Certificate Policy. ++ ++ Certificate Policy (CP): Specifies the criteria that a Certification ++ Authority undertakes to meet in its issue of certificates. See ++ [RFC3647]. ++ ++ Certification Practices Statement (CPS): Specifies the means by ++ which the criteria of the Certificate Policy are met. In most ++ cases, this will be the document against which the operations of ++ the Certification Authority are audited. See [RFC3647]. ++ ++ Domain: A DNS Domain Name. ++ ++ Domain Name: A DNS Domain Name as specified in [STD13]. ++ ++ Domain Name System (DNS): The Internet naming system specified in ++ [STD13]. ++ ++ DNS Security (DNSSEC): Extensions to the DNS that provide ++ authentication services as specified in [RFC4033], [RFC4034], ++ [RFC4035], [RFC5155], and revisions. ++ ++ Issuer: An entity that issues certificates. See [RFC5280]. ++ ++ Property: The tag-value portion of a CAA Resource Record. ++ ++ Property Tag: The tag portion of a CAA Resource Record. ++ ++ Property Value: The value portion of a CAA Resource Record. ++ ++ Public Key Infrastructure X.509 (PKIX): Standards and specifications ++ issued by the IETF that apply the [X.509] certificate standards ++ specified by the ITU to Internet applications as specified in ++ [RFC5280] and related documents. ++ ++ Resource Record (RR): A particular entry in the DNS including the ++ owner name, class, type, time to live, and data, as defined in ++ [STD13] and [RFC2181]. ++ ++ Resource Record Set (RRSet): A set of Resource Records or a ++ particular owner name, class, and type. The time to live on all ++ RRs with an RRSet is always the same, but the data may be ++ different among RRs in the RRSet. ++ ++ ++ ++Hallam-Baker & Stradling Standards Track [Page 4] ++ ++RFC 6844 Certification Authority Authorization January 2013 ++ ++ ++ Relying Party: A party that makes use of an application whose ++ operation depends on use of a certificate for making a security ++ decision. See [RFC5280]. ++ ++ Relying Application: An application whose operation depends on use ++ of a certificate for making a security decision. ++ ++3. The CAA RR Type ++ ++ A CAA RR consists of a flags byte and a tag-value pair referred to as ++ a property. Multiple properties MAY be associated with the same ++ domain name by publishing multiple CAA RRs at that domain name. The ++ following flag is defined: ++ ++ Issuer Critical: If set to '1', indicates that the corresponding ++ property tag MUST be understood if the semantics of the CAA record ++ are to be correctly interpreted by an issuer. ++ ++ Issuers MUST NOT issue certificates for a domain if the relevant ++ CAA Resource Record set contains unknown property tags that have ++ the Critical bit set. ++ ++ The following property tags are defined: ++ ++ issue [; = ]* : The issue property ++ entry authorizes the holder of the domain name or a party acting under the explicit authority of the holder ++ of that domain name to issue certificates for the domain in which ++ the property is published. ++ ++ issuewild [; = ]* : The issuewild ++ property entry authorizes the holder of the domain name or a party acting under the explicit authority of the ++ holder of that domain name to issue wildcard certificates for the ++ domain in which the property is published. ++ ++ iodef : Specifies a URL to which an issuer MAY report ++ certificate issue requests that are inconsistent with the issuer's ++ Certification Practices or Certificate Policy, or that a ++ Certificate Evaluator may use to report observation of a possible ++ policy violation. The Incident Object Description Exchange Format ++ (IODEF) format is used [RFC5070]. ++ ++ The following example is a DNS zone file (see [RFC1035]) that informs ++ CAs that certificates are not to be issued except by the holder of ++ the domain name 'ca.example.net' or an authorized agent thereof. ++ This policy applies to all subordinate domains under example.com. ++ ++ ++ ++ ++Hallam-Baker & Stradling Standards Track [Page 5] ++ ++RFC 6844 Certification Authority Authorization January 2013 ++ ++ ++ $ORIGIN example.com ++ . CAA 0 issue "ca.example.net" ++ ++ If the domain name holder specifies one or more iodef properties, a ++ certificate issuer MAY report invalid certificate requests to that ++ address. In the following example, the domain name holder specifies ++ that reports may be made by means of email with the IODEF data as an ++ attachment, a Web service [RFC6546], or both: ++ ++ $ORIGIN example.com ++ . CAA 0 issue "ca.example.net" ++ . CAA 0 iodef "mailto:security@example.com" ++ . CAA 0 iodef "http://iodef.example.com/" ++ ++ A certificate issuer MAY specify additional parameters that allow ++ customers to specify additional parameters governing certificate ++ issuance. This might be the Certificate Policy under which the ++ certificate is to be issued, the authentication process to be used ++ might be specified, or an account number specified by the CA to ++ enable these parameters to be retrieved. ++ ++ For example, the CA 'ca.example.net' has requested its customer ++ 'example.com' to specify the CA's account number '230123' in each of ++ the customer's CAA records. ++ ++ $ORIGIN example.com ++ . CAA 0 issue "ca.example.net; account=230123" ++ ++ The syntax of additional parameters is a sequence of name-value pairs ++ as defined in Section 5.2. The semantics of such parameters is left ++ to site policy and is outside the scope of this document. ++ ++ The critical flag is intended to permit future versions CAA to ++ introduce new semantics that MUST be understood for correct ++ processing of the record, preventing conforming CAs that do not ++ recognize the new semantics from issuing certificates for the ++ indicated domains. ++ ++ In the following example, the property 'tbs' is flagged as critical. ++ Neither the example.net CA nor any other issuer is authorized to ++ issue under either policy unless the processing rules for the 'tbs' ++ property tag are understood. ++ ++ $ORIGIN example.com ++ . CAA 0 issue "ca.example.net; policy=ev" ++ . CAA 128 tbs "Unknown" ++ ++ ++ ++ ++ ++Hallam-Baker & Stradling Standards Track [Page 6] ++ ++RFC 6844 Certification Authority Authorization January 2013 ++ ++ ++ Note that the above restrictions only apply at certificate issue. ++ Since the validity of an end entity certificate is typically a year ++ or more, it is quite possible that the CAA records published at a ++ domain will change between the time a certificate was issued and ++ validation by a relying party. ++ ++4. Certification Authority Processing ++ ++ Before issuing a certificate, a compliant CA MUST check for ++ publication of a relevant CAA Resource Record set. If such a record ++ set exists, a CA MUST NOT issue a certificate unless the CA ++ determines that either (1) the certificate request is consistent with ++ the applicable CAA Resource Record set or (2) an exception specified ++ in the relevant Certificate Policy or Certification Practices ++ Statement applies. ++ ++ A certificate request MAY specify more than one domain name and MAY ++ specify wildcard domains. Issuers MUST verify authorization for all ++ the domains and wildcard domains specified in the request. ++ ++ The search for a CAA record climbs the DNS name tree from the ++ specified label up to but not including the DNS root '.'. ++ ++ Given a request for a specific domain X, or a request for a wildcard ++ domain *.X, the relevant record set R(X) is determined as follows: ++ ++ Let CAA(X) be the record set returned in response to performing a CAA ++ record query on the label X, P(X) be the DNS label immediately above ++ X in the DNS hierarchy, and A(X) be the target of a CNAME or DNAME ++ alias record specified at the label X. ++ ++ o If CAA(X) is not empty, R(X) = CAA (X), otherwise ++ ++ o If A(X) is not null, and R(A(X)) is not empty, then R(X) = ++ R(A(X)), otherwise ++ ++ o If X is not a top-level domain, then R(X) = R(P(X)), otherwise ++ ++ o R(X) is empty. ++ ++ For example, if a certificate is requested for X.Y.Z the issuer will ++ search for the relevant CAA record set in the following order: ++ ++ X.Y.Z ++ ++ Alias (X.Y.Z) ++ ++ Y.Z ++ ++ ++ ++Hallam-Baker & Stradling Standards Track [Page 7] ++ ++RFC 6844 Certification Authority Authorization January 2013 ++ ++ ++ Alias (Y.Z) ++ ++ Z ++ ++ Alias (Z) ++ ++ Return Empty ++ ++4.1. Use of DNS Security ++ ++ Use of DNSSEC to authenticate CAA RRs is strongly RECOMMENDED but not ++ required. An issuer MUST NOT issue certificates if doing so would ++ conflict with the relevant CAA Resource Record set, irrespective of ++ whether the corresponding DNS records are signed. ++ ++ DNSSEC provides a proof of non-existence for both DNS domains and RR ++ set within domains. DNSSEC verification thus enables an issuer to ++ determine if the answer to a CAA record query is empty because the RR ++ set is empty or if it is non-empty but the response has been ++ suppressed. ++ ++ Use of DNSSEC allows an issuer to acquire and archive a proof that ++ they were authorized to issue certificates for the domain. ++ Verification of such archives MAY be an audit requirement to verify ++ CAA record processing compliance. Publication of such archives MAY ++ be a transparency requirement to verify CAA record processing ++ compliance. ++ ++5. Mechanism ++ ++5.1. Syntax ++ ++ A CAA RR contains a single property entry consisting of a tag-value ++ pair. Each tag represents a property of the CAA record. The value ++ of a CAA property is that specified in the corresponding value field. ++ ++ A domain name MAY have multiple CAA RRs associated with it and a ++ given property MAY be specified more than once. ++ ++ The CAA data field contains one property entry. A property entry ++ consists of the following data fields: ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++Hallam-Baker & Stradling Standards Track [Page 8] ++ ++RFC 6844 Certification Authority Authorization January 2013 ++ ++ ++ +0-1-2-3-4-5-6-7-|0-1-2-3-4-5-6-7-| ++ | Flags | Tag Length = n | ++ +----------------+----------------+...+---------------+ ++ | Tag char 0 | Tag char 1 |...| Tag char n-1 | ++ +----------------+----------------+...+---------------+ ++ +----------------+----------------+.....+----------------+ ++ | Value byte 0 | Value byte 1 |.....| Value byte m-1 | ++ +----------------+----------------+.....+----------------+ ++ ++ Where n is the length specified in the Tag length field and m is the ++ remaining octets in the Value field (m = d - n - 2) where d is the ++ length of the RDATA section. ++ ++ The data fields are defined as follows: ++ ++ Flags: One octet containing the following fields: ++ ++ Bit 0, Issuer Critical Flag: If the value is set to '1', the ++ critical flag is asserted and the property MUST be understood ++ if the CAA record is to be correctly processed by a certificate ++ issuer. ++ ++ A Certification Authority MUST NOT issue certificates for any ++ Domain that contains a CAA critical property for an unknown or ++ unsupported property tag that for which the issuer critical ++ flag is set. ++ ++ Note that according to the conventions set out in [RFC1035], bit 0 ++ is the Most Significant Bit and bit 7 is the Least Significant ++ Bit. Thus, the Flags value 1 means that bit 7 is set while a value ++ of 128 means that bit 0 is set according to this convention. ++ ++ All other bit positions are reserved for future use. ++ ++ To ensure compatibility with future extensions to CAA, DNS records ++ compliant with this version of the CAA specification MUST clear ++ (set to "0") all reserved flags bits. Applications that interpret ++ CAA records MUST ignore the value of all reserved flag bits. ++ ++ Tag Length: A single octet containing an unsigned integer specifying ++ the tag length in octets. The tag length MUST be at least 1 and ++ SHOULD be no more than 15. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++Hallam-Baker & Stradling Standards Track [Page 9] ++ ++RFC 6844 Certification Authority Authorization January 2013 ++ ++ ++ Tag: The property identifier, a sequence of US-ASCII characters. ++ ++ Tag values MAY contain US-ASCII characters 'a' through 'z', 'A' ++ through 'Z', and the numbers 0 through 9. Tag values SHOULD NOT ++ contain any other characters. Matching of tag values is case ++ insensitive. ++ ++ Tag values submitted for registration by IANA MUST NOT contain any ++ characters other than the (lowercase) US-ASCII characters 'a' ++ through 'z' and the numbers 0 through 9. ++ ++ Value: A sequence of octets representing the property value. ++ Property values are encoded as binary values and MAY employ sub- ++ formats. ++ ++ The length of the value field is specified implicitly as the ++ remaining length of the enclosing Resource Record data field. ++ ++5.1.1. Canonical Presentation Format ++ ++ The canonical presentation format of the CAA record is: ++ ++ CAA ++ ++ Where: ++ ++ Flags: Is an unsigned integer between 0 and 255. ++ ++ Tag: Is a non-zero sequence of US-ASCII letters and numbers in lower ++ case. ++ ++ Value: Is the encoding of the value field as ++ specified in [RFC1035], Section 5.1. ++ ++5.2. CAA issue Property ++ ++ The issue property tag is used to request that certificate issuers ++ perform CAA issue restriction processing for the domain and to grant ++ authorization to specific certificate issuers. ++ ++ The CAA issue property value has the following sub-syntax (specified ++ in ABNF as per [RFC5234]). ++ ++ ++ ++ ++ ++ ++ ++ ++ ++Hallam-Baker & Stradling Standards Track [Page 10] ++ ++RFC 6844 Certification Authority Authorization January 2013 ++ ++ ++ issuevalue = space [domain] space [";" *(space parameter) space] ++ ++ domain = label *("." label) ++ label = (ALPHA / DIGIT) *( *("-") (ALPHA / DIGIT)) ++ ++ space = *(SP / HTAB) ++ ++ parameter = tag "=" value ++ ++ tag = 1*(ALPHA / DIGIT) ++ ++ value = *VCHAR ++ ++ For consistency with other aspects of DNS administration, domain name ++ values are specified in letter-digit-hyphen Label (LDH-Label) form. ++ ++ A CAA record with an issue parameter tag that does not specify a ++ domain name is a request that certificate issuers perform CAA issue ++ restriction processing for the corresponding domain without granting ++ authorization to any certificate issuer. ++ ++ This form of issue restriction would be appropriate to specify that ++ no certificates are to be issued for the domain in question. ++ ++ For example, the following CAA record set requests that no ++ certificates be issued for the domain 'nocerts.example.com' by any ++ certificate issuer. ++ ++ nocerts.example.com CAA 0 issue ";" ++ ++ A CAA record with an issue parameter tag that specifies a domain name ++ is a request that certificate issuers perform CAA issue restriction ++ processing for the corresponding domain and grants authorization to ++ the certificate issuer specified by the domain name. ++ ++ For example, the following CAA record set requests that no ++ certificates be issued for the domain 'certs.example.com' by any ++ certificate issuer other than the example.net certificate issuer. ++ ++ certs.example.com CAA 0 issue "example.net" ++ ++ CAA authorizations are additive; thus, the result of specifying both ++ the empty issuer and a specified issuer is the same as specifying ++ just the specified issuer alone. ++ ++ ++ ++ ++ ++ ++ ++Hallam-Baker & Stradling Standards Track [Page 11] ++ ++RFC 6844 Certification Authority Authorization January 2013 ++ ++ ++ An issuer MAY choose to specify issuer-parameters that further ++ constrain the issue of certificates by that issuer, for example, ++ specifying that certificates are to be subject to specific validation ++ polices, billed to certain accounts, or issued under specific trust ++ anchors. ++ ++ The semantics of issuer-parameters are determined by the issuer ++ alone. ++ ++5.3. CAA issuewild Property ++ ++ The issuewild property has the same syntax and semantics as the issue ++ property except that issuewild properties only grant authorization to ++ issue certificates that specify a wildcard domain and issuewild ++ properties take precedence over issue properties when specified. ++ Specifically: ++ ++ issuewild properties MUST be ignored when processing a request for ++ a domain that is not a wildcard domain. ++ ++ If at least one issuewild property is specified in the relevant ++ CAA record set, all issue properties MUST be ignored when ++ processing a request for a domain that is a wildcard domain. ++ ++5.4. CAA iodef Property ++ ++ The iodef property specifies a means of reporting certificate issue ++ requests or cases of certificate issue for the corresponding domain ++ that violate the security policy of the issuer or the domain name ++ holder. ++ ++ The Incident Object Description Exchange Format (IODEF) [RFC5070] is ++ used to present the incident report in machine-readable form. ++ ++ The iodef property takes a URL as its parameter. The URL scheme type ++ determines the method used for reporting: ++ ++ mailto: The IODEF incident report is reported as a MIME email ++ attachment to an SMTP email that is submitted to the mail address ++ specified. The mail message sent SHOULD contain a brief text ++ message to alert the recipient to the nature of the attachment. ++ ++ http or https: The IODEF report is submitted as a Web service ++ request to the HTTP address specified using the protocol specified ++ in [RFC6546]. ++ ++ ++ ++ ++ ++ ++Hallam-Baker & Stradling Standards Track [Page 12] ++ ++RFC 6844 Certification Authority Authorization January 2013 ++ ++ ++6. Security Considerations ++ ++ CAA records assert a security policy that the holder of a domain name ++ wishes to be observed by certificate issuers. The effectiveness of ++ CAA records as an access control mechanism is thus dependent on ++ observance of CAA constraints by issuers. ++ ++ The objective of the CAA record properties described in this document ++ is to reduce the risk of certificate mis-issue rather than avoid ++ reliance on a certificate that has been mis-issued. DANE [RFC6698] ++ describes a mechanism for avoiding reliance on mis-issued ++ certificates. ++ ++6.1. Non-Compliance by Certification Authority ++ ++ CAA records offer CAs a cost-effective means of mitigating the risk ++ of certificate mis-issue: the cost of implementing CAA checks is very ++ small and the potential costs of a mis-issue event include the ++ removal of an embedded trust anchor. ++ ++6.2. Mis-Issue by Authorized Certification Authority ++ ++ Use of CAA records does not prevent mis-issue by an authorized ++ Certification Authority, i.e., a CA that is authorized to issue ++ certificates for the domain in question by CAA records. ++ ++ Domain name holders SHOULD verify that the CAs they authorize to ++ issue certificates for their domains employ appropriate controls to ++ ensure that certificates are issued only to authorized parties within ++ their organization. ++ ++ Such controls are most appropriately determined by the domain name ++ holder and the authorized CA(s) directly and are thus out of scope of ++ this document. ++ ++6.3. Suppression or Spoofing of CAA Records ++ ++ Suppression of the CAA record or insertion of a bogus CAA record ++ could enable an attacker to obtain a certificate from an issuer that ++ was not authorized to issue for that domain name. ++ ++ Where possible, issuers SHOULD perform DNSSEC validation to detect ++ missing or modified CAA record sets. ++ ++ In cases where DNSSEC is not deployed in a corresponding domain, an ++ issuer SHOULD attempt to mitigate this risk by employing appropriate ++ DNS security controls. For example, all portions of the DNS lookup ++ ++ ++ ++ ++Hallam-Baker & Stradling Standards Track [Page 13] ++ ++RFC 6844 Certification Authority Authorization January 2013 ++ ++ ++ process SHOULD be performed against the authoritative name server. ++ Data cached by third parties MUST NOT be relied on but MAY be used to ++ support additional anti-spoofing or anti-suppression controls. ++ ++6.4. Denial of Service ++ ++ Introduction of a malformed or malicious CAA RR could in theory ++ enable a Denial-of-Service (DoS) attack. ++ ++ This specific threat is not considered to add significantly to the ++ risk of running an insecure DNS service. ++ ++ An attacker could, in principle, perform a DoS attack against an ++ issuer by requesting a certificate with a maliciously long DNS name. ++ In practice, the DNS protocol imposes a maximum name length and CAA ++ processing does not exacerbate the existing need to mitigate DoS ++ attacks to any meaningful degree. ++ ++6.5. Abuse of the Critical Flag ++ ++ A Certification Authority could make use of the critical flag to ++ trick customers into publishing records that prevent competing ++ Certification Authorities from issuing certificates even though the ++ customer intends to authorize multiple providers. ++ ++ In practice, such an attack would be of minimal effect since any ++ competent competitor that found itself unable to issue certificates ++ due to lack of support for a property marked critical SHOULD ++ investigate the cause and report the reason to the customer. The ++ customer will thus discover that they had been deceived. ++ ++7. IANA Considerations ++ ++7.1. Registration of the CAA Resource Record Type ++ ++ IANA has assigned Resource Record Type 257 for the CAA Resource ++ Record Type and added the line depicted below to the registry named ++ "Resource Record (RR) TYPEs" and QTYPEs as defined in BCP 42 ++ [RFC6195] and located at ++ http://www.iana.org/assignments/dns-parameters. ++ ++ RR Name Value and meaning Reference ++ ----------- --------------------------------------------- --------- ++ CAA 257 Certification Authority Restriction [RFC6844] ++ ++ ++ ++ ++ ++ ++ ++Hallam-Baker & Stradling Standards Track [Page 14] ++ ++RFC 6844 Certification Authority Authorization January 2013 ++ ++ ++7.2. Certification Authority Restriction Properties ++ ++ IANA has created the "Certification Authority Restriction Properties" ++ registry with the following initial values: ++ ++ ++ Tag Meaning Reference ++ ----------- -------------------------------------- --------- ++ issue Authorization Entry by Domain [RFC6844] ++ issuewild Authorization Entry by Wildcard Domain [RFC6844] ++ iodef Report incident by IODEF report [RFC6844] ++ auth Reserved [HB2011] ++ path Reserved [HB2011] ++ policy Reserved [HB2011] ++ ++ ++ Although [HB2011] has expired, deployed clients implement the CAA ++ properties specified in the document and reuse of these property tags ++ for a different purpose could cause unexpected behavior. ++ ++ Addition of tag identifiers requires a public specification and ++ Expert Review as set out in [RFC6195], Section 3.1.1. ++ ++ The tag space is designed to be sufficiently large that exhausting ++ the possible tag space need not be a concern. The scope of Expert ++ Review SHOULD be limited to the question of whether the specification ++ provided is sufficiently clear to permit implementation and to avoid ++ unnecessary duplication of functionality. ++ ++7.3. Certification Authority Restriction Flags ++ ++ IANA has created the "Certification Authority Restriction Flags" ++ registry with the following initial values: ++ ++ ++ Flag Meaning Reference ++ ----------- ---------------------------------- --------- ++ 0 Issuer Critical Flag [RFC6844] ++ 1-7 Reserved> [RFC6844] ++ ++ Assignment of new flags follows the RFC Required policy set out in ++ [RFC5226], Section 4.1. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++Hallam-Baker & Stradling Standards Track [Page 15] ++ ++RFC 6844 Certification Authority Authorization January 2013 ++ ++ ++8. Acknowledgements ++ ++ The authors would like to thank the following people who contributed ++ to the design and documentation of this work item: Chris Evans, ++ Stephen Farrell, Jeff Hodges, Paul Hoffman, Stephen Kent, Adam ++ Langley, Ben Laurie, James Manager, Chris Palmer, Scott Schmit, Sean ++ Turner, and Ben Wilson. ++ ++9. References ++ ++9.1. Normative References ++ ++ [RFC1035] Mockapetris, P., "Domain names - implementation and ++ specification", STD 13, RFC 1035, November 1987. ++ ++ [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate ++ Requirement Levels", BCP 14, RFC 2119, March 1997. ++ ++ [RFC2181] Elz, R. and R. Bush, "Clarifications to the DNS ++ Specification", RFC 2181, July 1997. ++ ++ [RFC4033] Arends, R., Austein, R., Larson, M., Massey, D., and S. ++ Rose, "DNS Security Introduction and Requirements", ++ RFC 4033, March 2005. ++ ++ [RFC4034] Arends, R., Austein, R., Larson, M., Massey, D., and S. ++ Rose, "Resource Records for the DNS Security Extensions", ++ RFC 4034, March 2005. ++ ++ [RFC4035] Arends, R., Austein, R., Larson, M., Massey, D., and S. ++ Rose, "Protocol Modifications for the DNS Security ++ Extensions", RFC 4035, March 2005. ++ ++ [RFC5070] Danyliw, R., Meijer, J., and Y. Demchenko, "The Incident ++ Object Description Exchange Format", RFC 5070, ++ December 2007. ++ ++ [RFC5155] Laurie, B., Sisson, G., Arends, R., and D. Blacka, "DNS ++ Security (DNSSEC) Hashed Authenticated Denial of ++ Existence", RFC 5155, March 2008. ++ ++ [RFC5226] Narten, T. and H. Alvestrand, "Guidelines for Writing an ++ IANA Considerations Section in RFCs", BCP 26, RFC 5226, ++ May 2008. ++ ++ [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax ++ Specifications: ABNF", STD 68, RFC 5234, January 2008. ++ ++ ++ ++ ++Hallam-Baker & Stradling Standards Track [Page 16] ++ ++RFC 6844 Certification Authority Authorization January 2013 ++ ++ ++ [RFC5280] Cooper, D., Santesson, S., Farrell, S., Boeyen, S., ++ Housley, R., and W. Polk, "Internet X.509 Public Key ++ Infrastructure Certificate and Certificate Revocation List ++ (CRL) Profile", RFC 5280, May 2008. ++ ++ [RFC6195] Eastlake, D., "Domain Name System (DNS) IANA ++ Considerations", BCP 42, RFC 6195, March 2011. ++ ++ [RFC6546] Trammell, B., "Transport of Real-time Inter-network ++ Defense (RID) Messages over HTTP/TLS", RFC 6546, ++ April 2012. ++ ++ [RFC6698] Hoffman, P. and J. Schlyter, "The DNS-Based Authentication ++ of Named Entities (DANE) Transport Layer Security (TLS) ++ Protocol: TLSA", RFC 6698, August 2012. ++ ++ [STD13] Mockapetris, P., "Domain names - concepts and facilities", ++ STD 13, RFC 1034, November 1987. ++ ++ Mockapetris, P., "Domain names - implementation and ++ specification", STD 13, RFC 1035, November 1987. ++ ++ [X.509] International Telecommunication Union, "ITU-T ++ Recommendation X.509 (11/2008): Information technology - ++ Open systems interconnection - The Directory: Public-key ++ and attribute certificate frameworks", ITU-T ++ Recommendation X.509, November 2008. ++ ++9.2. Informative References ++ ++ [HB2011] Hallam-Baker, P., Stradling, R., and B. Laurie, "DNS ++ Certification Authority Authorization (CAA) Resource ++ Record", Work in Progress, May 2011. ++ ++ [RFC3647] Chokhani, S., Ford, W., Sabett, R., Merrill, C., and S. ++ Wu, "Internet X.509 Public Key Infrastructure Certificate ++ Policy and Certification Practices Framework", RFC 3647, ++ November 2003. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++Hallam-Baker & Stradling Standards Track [Page 17] ++ ++RFC 6844 Certification Authority Authorization January 2013 ++ ++ ++Authors' Addresses ++ ++ Phillip Hallam-Baker ++ Comodo Group, Inc. ++ ++ EMail: philliph@comodo.com ++ ++ ++ Rob Stradling ++ Comodo CA, Ltd. ++ ++ EMail: rob.stradling@comodo.com ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++Hallam-Baker & Stradling Standards Track [Page 18] ++ +diff --git a/lib/dns/rdata.c b/lib/dns/rdata.c +index a83dab4..9bf83a4 100644 +--- a/lib/dns/rdata.c ++++ b/lib/dns/rdata.c +@@ -116,7 +116,7 @@ typedef struct dns_rdata_textctx { + } dns_rdata_textctx_t; + + static isc_result_t +-txt_totext(isc_region_t *source, isc_buffer_t *target); ++txt_totext(isc_region_t *source, isc_boolean_t quote, isc_buffer_t *target); + + static isc_result_t + txt_fromtext(isc_textregion_t *source, isc_buffer_t *target); +@@ -130,9 +130,6 @@ 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 isc_result_t +-multitxt_fromwire(isc_buffer_t *source, isc_buffer_t *target); +- + static isc_boolean_t + name_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target); + +@@ -1131,7 +1128,7 @@ name_length(dns_name_t *name) { + } + + static isc_result_t +-txt_totext(isc_region_t *source, isc_buffer_t *target) { ++txt_totext(isc_region_t *source, isc_boolean_t quote, isc_buffer_t *target) { + unsigned int tl; + unsigned int n; + unsigned char *sp; +@@ -1146,13 +1143,20 @@ txt_totext(isc_region_t *source, isc_buffer_t *target) { + n = *sp++; + + REQUIRE(n + 1 <= source->length); ++ if (n == 0U) ++ REQUIRE(quote == ISC_TRUE); + +- if (tl < 1) +- return (ISC_R_NOSPACE); +- *tp++ = '"'; +- tl--; ++ if (quote) { ++ if (tl < 1) ++ return (ISC_R_NOSPACE); ++ *tp++ = '"'; ++ tl--; ++ } + while (n--) { +- if (*sp < 0x20 || *sp >= 0x7f) { ++ /* ++ * \DDD space (0x20) if not quoting. ++ */ ++ if (*sp < (quote ? 0x20 : 0x21) || *sp >= 0x7f) { + if (tl < 4) + return (ISC_R_NOSPACE); + *tp++ = 0x5c; +@@ -1163,8 +1167,13 @@ txt_totext(isc_region_t *source, isc_buffer_t *target) { + tl -= 4; + continue; + } +- /* double quote, semi-colon, backslash */ +- if (*sp == 0x22 || *sp == 0x3b || *sp == 0x5c) { ++ /* ++ * Escape double quote, semi-colon, backslash. ++ * If we are not enclosing the string in double ++ * quotes also escape at sign. ++ */ ++ if (*sp == 0x22 || *sp == 0x3b || *sp == 0x5c || ++ (!quote && *sp == 0x40)) { + if (tl < 2) + return (ISC_R_NOSPACE); + *tp++ = '\\'; +@@ -1175,10 +1184,12 @@ txt_totext(isc_region_t *source, isc_buffer_t *target) { + *tp++ = *sp++; + tl--; + } +- if (tl < 1) +- return (ISC_R_NOSPACE); +- *tp++ = '"'; +- tl--; ++ if (quote) { ++ if (tl < 1) ++ return (ISC_R_NOSPACE); ++ *tp++ = '"'; ++ tl--; ++ } + isc_buffer_add(target, tp - (char *)region.base); + isc_region_consume(source, *source->base + 1); + return (ISC_R_SUCCESS); +@@ -1274,6 +1285,9 @@ txt_fromwire(isc_buffer_t *source, isc_buffer_t *target) { + 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; +@@ -1292,9 +1306,8 @@ multitxt_totext(isc_region_t *source, isc_buffer_t *target) { + *tp++ = '"'; + tl--; + do { +- n0 = n = *sp++; +- +- REQUIRE(n0 + 1 <= source->length); ++ n = source->length; ++ n0 = source->length - 1; + + while (n--) { + if (*sp < 0x20 || *sp >= 0x7f) { +@@ -1346,17 +1359,11 @@ multitxt_fromtext(isc_textregion_t *source, isc_buffer_t *target) { + + do { + isc_buffer_availableregion(target, &tregion); +- t0 = tregion.base; ++ t0 = t = tregion.base; + nrem = tregion.length; + if (nrem < 1) + return (ISC_R_NOSPACE); +- /* length byte */ +- t = t0; +- nrem--; +- t++; +- /* 255 byte character-string slice */ +- if (nrem > 255) +- nrem = 255; ++ + while (n != 0) { + --n; + c = (*s++) & 0xff; +@@ -1390,39 +1397,9 @@ multitxt_fromtext(isc_textregion_t *source, isc_buffer_t *target) { + } + if (escape) + return (DNS_R_SYNTAX); +- *t0 = t - t0 - 1; +- isc_buffer_add(target, *t0 + 1); +- } while (n != 0); +- return (ISC_R_SUCCESS); +-} +- +-static isc_result_t +-multitxt_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 = 256U; +- do { +- if (n != 256U) +- return (DNS_R_SYNTAX); +- 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) +- memcpy(tregion.base, sregion.base, n); +- isc_buffer_forward(source, n); +- isc_buffer_add(target, n); +- isc_buffer_activeregion(source, &sregion); +- } while (sregion.length != 0); ++ isc_buffer_add(target, t - t0); ++ } while (n != 0); + return (ISC_R_SUCCESS); + } + +diff --git a/lib/dns/rdata/generic/caa_257.c b/lib/dns/rdata/generic/caa_257.c +new file mode 100644 +index 0000000..671f332 +--- /dev/null ++++ b/lib/dns/rdata/generic/caa_257.c +@@ -0,0 +1,370 @@ ++/* ++ * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") ++ * ++ * 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 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 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; ++ isc_uint8_t flags; ++ unsigned int i; ++ ++ REQUIRE(type == 257); ++ ++ UNUSED(type); ++ UNUSED(rdclass); ++ UNUSED(origin); ++ UNUSED(options); ++ UNUSED(callbacks); ++ ++ /* Flags. */ ++ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ++ ISC_FALSE)); ++ if (token.value.as_ulong > 255U) ++ RETTOK(ISC_R_RANGE); ++ flags = token.value.as_ulong & 255U; ++ RETERR(uint8_tobuffer(flags, target)); ++ ++ /* ++ * Tag ++ */ ++ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ++ ISC_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, ISC_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; ++ isc_uint8_t flags; ++ char buf[256]; ++ ++ UNUSED(tctx); ++ ++ REQUIRE(rdata->type == 257); ++ REQUIRE(rdata->length >= 3U); ++ REQUIRE(rdata->data != NULL); ++ ++ dns_rdata_toregion(rdata, ®ion); ++ ++ /* ++ * Flags ++ */ ++ flags = uint8_consume_fromregion(®ion); ++ sprintf(buf, "%u ", flags); ++ RETERR(str_totext(buf, target)); ++ ++ /* ++ * Tag ++ */ ++ RETERR(txt_totext(®ion, ISC_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 == 257); ++ ++ 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 == 257); ++ 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 == 257); ++ 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 = source; ++ isc_region_t region; ++ unsigned int i; ++ ++ REQUIRE(type == 257); ++ REQUIRE(source != NULL); ++ REQUIRE(caa->common.rdtype == type); ++ REQUIRE(caa->common.rdclass == rdclass); ++ REQUIRE(caa->tag != NULL && caa->tag_len != 0); ++ REQUIRE(caa->value != NULL); ++ ++ 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 = target; ++ isc_region_t sr; ++ ++ REQUIRE(rdata->type == 257); ++ REQUIRE(target != NULL); ++ REQUIRE(rdata->length >= 3U); ++ REQUIRE(rdata->data != NULL); ++ ++ 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 = (dns_rdata_caa_t *) source; ++ ++ REQUIRE(source != NULL); ++ REQUIRE(caa->common.rdtype == 257); ++ ++ 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 == 257); ++ 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 == 257); ++ REQUIRE(rdata->data != NULL); ++ REQUIRE(rdata->length >= 3U); ++ ++ dns_rdata_toregion(rdata, &r); ++ ++ return ((digest)(arg, &r)); ++} ++ ++static inline isc_boolean_t ++checkowner_caa(ARGS_CHECKOWNER) { ++ ++ REQUIRE(type == 257); ++ ++ UNUSED(name); ++ UNUSED(type); ++ UNUSED(rdclass); ++ UNUSED(wildcard); ++ ++ return (ISC_TRUE); ++} ++ ++static inline isc_boolean_t ++checknames_caa(ARGS_CHECKNAMES) { ++ ++ REQUIRE(rdata->type == 257); ++ REQUIRE(rdata->data != NULL); ++ REQUIRE(rdata->length >= 3U); ++ ++ UNUSED(rdata); ++ UNUSED(owner); ++ UNUSED(bad); ++ ++ return (ISC_TRUE); ++} ++ ++static inline int ++casecompare_caa(ARGS_COMPARE) { ++ return (compare_caa(rdata1, rdata2)); ++} ++ ++#endif /* GENERIC_CAA_257_C */ +diff --git a/lib/dns/rdata/generic/caa_257.h b/lib/dns/rdata/generic/caa_257.h +new file mode 100644 +index 0000000..79866a5 +--- /dev/null ++++ b/lib/dns/rdata/generic/caa_257.h +@@ -0,0 +1,32 @@ ++/* ++ * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") ++ * ++ * 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 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 GENERIC_CAA_257_H ++#define GENERIC_CAA_257_H 1 ++ ++/* $Id$ */ ++ ++typedef struct dns_rdata_caa { ++ dns_rdatacommon_t common; ++ isc_mem_t * mctx; ++ isc_uint8_t flags; ++ unsigned char * tag; ++ isc_uint8_t tag_len; ++ unsigned char *value; ++ isc_uint8_t value_len; ++} dns_rdata_caa_t; ++ ++#endif /* GENERIC_CAA_257_H */ +diff --git a/lib/dns/rdata/generic/gpos_27.c b/lib/dns/rdata/generic/gpos_27.c +index ce71822..5a90216 100644 +--- a/lib/dns/rdata/generic/gpos_27.c ++++ b/lib/dns/rdata/generic/gpos_27.c +@@ -61,7 +61,7 @@ totext_gpos(ARGS_TOTEXT) { + dns_rdata_toregion(rdata, ®ion); + + for (i = 0; i < 3; i++) { +- RETERR(txt_totext(®ion, target)); ++ RETERR(txt_totext(®ion, ISC_TRUE, target)); + if (i != 2) + RETERR(str_totext(" ", target)); + } +diff --git a/lib/dns/rdata/generic/hinfo_13.c b/lib/dns/rdata/generic/hinfo_13.c +index 10b4fec..92038b7 100644 +--- a/lib/dns/rdata/generic/hinfo_13.c ++++ b/lib/dns/rdata/generic/hinfo_13.c +@@ -58,9 +58,9 @@ totext_hinfo(ARGS_TOTEXT) { + REQUIRE(rdata->length != 0); + + dns_rdata_toregion(rdata, ®ion); +- RETERR(txt_totext(®ion, target)); ++ RETERR(txt_totext(®ion, ISC_TRUE, target)); + RETERR(str_totext(" ", target)); +- return (txt_totext(®ion, target)); ++ return (txt_totext(®ion, ISC_TRUE, target)); + } + + static inline isc_result_t +diff --git a/lib/dns/rdata/generic/isdn_20.c b/lib/dns/rdata/generic/isdn_20.c +index 5aac73f..059c247 100644 +--- a/lib/dns/rdata/generic/isdn_20.c ++++ b/lib/dns/rdata/generic/isdn_20.c +@@ -65,11 +65,11 @@ totext_isdn(ARGS_TOTEXT) { + UNUSED(tctx); + + dns_rdata_toregion(rdata, ®ion); +- RETERR(txt_totext(®ion, target)); ++ RETERR(txt_totext(®ion, ISC_TRUE, target)); + if (region.length == 0) + return (ISC_R_SUCCESS); + RETERR(str_totext(" ", target)); +- return (txt_totext(®ion, target)); ++ return (txt_totext(®ion, ISC_TRUE, target)); + } + + static inline isc_result_t +diff --git a/lib/dns/rdata/generic/naptr_35.c b/lib/dns/rdata/generic/naptr_35.c +index 83439a5..be7d403 100644 +--- a/lib/dns/rdata/generic/naptr_35.c ++++ b/lib/dns/rdata/generic/naptr_35.c +@@ -224,19 +224,19 @@ totext_naptr(ARGS_TOTEXT) { + /* + * Flags. + */ +- RETERR(txt_totext(®ion, target)); ++ RETERR(txt_totext(®ion, ISC_TRUE, target)); + RETERR(str_totext(" ", target)); + + /* + * Service. + */ +- RETERR(txt_totext(®ion, target)); ++ RETERR(txt_totext(®ion, ISC_TRUE, target)); + RETERR(str_totext(" ", target)); + + /* + * Regexp. + */ +- RETERR(txt_totext(®ion, target)); ++ RETERR(txt_totext(®ion, ISC_TRUE, target)); + RETERR(str_totext(" ", target)); + + /* +diff --git a/lib/dns/rdata/generic/spf_99.c b/lib/dns/rdata/generic/spf_99.c +index 492e315..85594fd 100644 +--- a/lib/dns/rdata/generic/spf_99.c ++++ b/lib/dns/rdata/generic/spf_99.c +@@ -64,7 +64,7 @@ totext_spf(ARGS_TOTEXT) { + dns_rdata_toregion(rdata, ®ion); + + while (region.length > 0) { +- RETERR(txt_totext(®ion, target)); ++ RETERR(txt_totext(®ion, ISC_TRUE, target)); + if (region.length > 0) + RETERR(str_totext(" ", target)); + } +diff --git a/lib/dns/rdata/generic/txt_16.c b/lib/dns/rdata/generic/txt_16.c +index e1bce6a..e0e8ea5 100644 +--- a/lib/dns/rdata/generic/txt_16.c ++++ b/lib/dns/rdata/generic/txt_16.c +@@ -71,7 +71,7 @@ totext_txt(ARGS_TOTEXT) { + dns_rdata_toregion(rdata, ®ion); + + while (region.length > 0) { +- RETERR(txt_totext(®ion, target)); ++ RETERR(txt_totext(®ion, ISC_TRUE, target)); + if (region.length > 0) + RETERR(str_totext(" ", target)); + } +diff --git a/lib/dns/rdata/generic/uri_256.c b/lib/dns/rdata/generic/uri_256.c +index 799eb69..62bdd25 100644 +--- a/lib/dns/rdata/generic/uri_256.c ++++ b/lib/dns/rdata/generic/uri_256.c +@@ -115,15 +115,12 @@ fromwire_uri(ARGS_FROMWIRE) { + isc_buffer_activeregion(source, ®ion); + if (region.length < 4) + return (ISC_R_UNEXPECTEDEND); +- RETERR(mem_tobuffer(target, region.base, 4)); +- isc_buffer_forward(source, 4); + + /* +- * Target URI ++ * Priority, weight and target URI + */ +- RETERR(multitxt_fromwire(source, target)); +- +- return (ISC_R_SUCCESS); ++ isc_buffer_forward(source, region.length); ++ return (mem_tobuffer(target, region.base, region.length)); + } + + static inline isc_result_t +@@ -178,8 +175,6 @@ compare_uri(ARGS_COMPARE) { + static inline isc_result_t + fromstruct_uri(ARGS_FROMSTRUCT) { + dns_rdata_uri_t *uri = source; +- isc_region_t region; +- isc_uint8_t len; + + REQUIRE(type == 256); + REQUIRE(source != NULL); +@@ -203,18 +198,6 @@ fromstruct_uri(ARGS_FROMSTRUCT) { + /* + * Target URI + */ +- len = 255U; +- region.base = uri->target; +- region.length = uri->tgt_len; +- while (region.length > 0) { +- REQUIRE(len == 255U); +- len = uint8_fromregion(®ion); +- isc_region_consume(®ion, 1); +- if (region.length < len) +- return (ISC_R_UNEXPECTEDEND); +- isc_region_consume(®ion, len); +- } +- + return (mem_tobuffer(target, uri->target, uri->tgt_len)); + } + +diff --git a/lib/dns/rdata/generic/x25_19.c b/lib/dns/rdata/generic/x25_19.c +index 6867fec..f9dfb8a 100644 +--- a/lib/dns/rdata/generic/x25_19.c ++++ b/lib/dns/rdata/generic/x25_19.c +@@ -60,7 +60,7 @@ totext_x25(ARGS_TOTEXT) { + REQUIRE(rdata->length != 0); + + dns_rdata_toregion(rdata, ®ion); +- return (txt_totext(®ion, target)); ++ return (txt_totext(®ion, ISC_TRUE, target)); + } + + static inline isc_result_t +-- +2.4.3 + diff --git a/SOURCES/named-chroot.service b/SOURCES/named-chroot.service index f8c0496..55bf507 100644 --- a/SOURCES/named-chroot.service +++ b/SOURCES/named-chroot.service @@ -16,7 +16,7 @@ EnvironmentFile=-/etc/sysconfig/named Environment=KRB5_KTNAME=/etc/named.keytab PIDFile=/var/named/chroot/run/named/named.pid -ExecStartPre=/bin/bash -c 'if [ ! "$DISABLE_ZONE_CHECKING" == "yes" ]; then /usr/sbin/named-checkconf -z /etc/named.conf; else echo "Checking of zone files is disabled"; fi' +ExecStartPre=/bin/bash -c 'if [ ! "$DISABLE_ZONE_CHECKING" == "yes" ]; then /usr/sbin/named-checkconf -t /var/named/chroot -z /etc/named.conf; else echo "Checking of zone files is disabled"; fi' ExecStart=/usr/sbin/named -u named -t /var/named/chroot $OPTIONS ExecReload=/bin/sh -c '/usr/sbin/rndc reload > /dev/null 2>&1 || /bin/kill -HUP $MAINPID' diff --git a/SOURCES/named-pkcs11.service b/SOURCES/named-pkcs11.service index 6ce9001..e522ec3 100644 --- a/SOURCES/named-pkcs11.service +++ b/SOURCES/named-pkcs11.service @@ -1,10 +1,9 @@ [Unit] Description=Berkeley Internet Name Domain (DNS) with native PKCS#11 Wants=nss-lookup.target -Wants=network-online.target Wants=named-setup-rndc.service Before=nss-lookup.target -After=network-online.target +After=network.target After=named-setup-rndc.service [Service] diff --git a/SOURCES/named-sdb-chroot.service b/SOURCES/named-sdb-chroot.service index 09b7974..2e42646 100644 --- a/SOURCES/named-sdb-chroot.service +++ b/SOURCES/named-sdb-chroot.service @@ -16,7 +16,7 @@ EnvironmentFile=-/etc/sysconfig/named Environment=KRB5_KTNAME=/etc/named.keytab PIDFile=/var/named/chroot_sdb/run/named/named.pid -ExecStartPre=/usr/sbin/named-checkconf -t /var/named/chroot_sdb -z /etc/named.conf +ExecStartPre=/bin/bash -c 'if [ ! "$DISABLE_ZONE_CHECKING" == "yes" ]; then /usr/sbin/named-checkconf -t /var/named/chroot_sdb -z /etc/named.conf; else echo "Checking of zone files is disabled"; fi' ExecStart=/usr/sbin/named-sdb -u named -t /var/named/chroot_sdb $OPTIONS ExecReload=/bin/sh -c '/usr/sbin/rndc reload > /dev/null 2>&1 || /bin/kill -HUP $MAINPID' diff --git a/SOURCES/named.NetworkManager b/SOURCES/named.NetworkManager deleted file mode 100644 index c835a00..0000000 --- a/SOURCES/named.NetworkManager +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -if [ "$2" = 'up' -o "$2" = 'down' ]; then - /usr/bin/systemctl reload named.service > /dev/null 2>&1 || true - /usr/bin/systemctl reload named-chroot.service > /dev/null 2>&1 || true - /usr/bin/systemctl reload named-sdb.service > /dev/null 2>&1 || true - /usr/bin/systemctl reload named-sdb-chroot.service > /dev/null 2>&1 || true -fi diff --git a/SOURCES/named.conf.sample b/SOURCES/named.conf.sample index afae47b..f091345 100644 --- a/SOURCES/named.conf.sample +++ b/SOURCES/named.conf.sample @@ -2,10 +2,8 @@ Sample named.conf BIND DNS server 'named' configuration file for the Red Hat BIND distribution. - See the BIND Administrator's Reference Manual (ARM) for details, in: - file:///usr/share/doc/bind-{version}/arm/Bv9ARM.html - Also see the BIND Configuration GUI : /usr/bin/system-config-bind and - its manual. + See the BIND Administrator's Reference Manual (ARM) for details about the + configuration located in /usr/share/doc/bind-{version}/Bv9ARM.html */ options diff --git a/SPECS/bind.spec b/SPECS/bind.spec index 5d516b5..638582e 100644 --- a/SPECS/bind.spec +++ b/SPECS/bind.spec @@ -25,21 +25,20 @@ Summary: The Berkeley Internet Name Domain (BIND) DNS (Domain Name System) serv Name: bind License: ISC Version: 9.9.4 -Release: 29%{?PATCHVER}%{?PREVER}%{?dist}.4 +Release: 37%{?PATCHVER}%{?PREVER}%{?dist} Epoch: 32 Url: http://www.isc.org/products/BIND/ Buildroot:%{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Group: System Environment/Daemons # -Source: ftp://ftp.isc.org/isc/bind9/%{VERSION}/bind-%{VERSION}.tar.gz +Source: https://ftp.isc.org/isc/bind9/%{VERSION}/bind-%{VERSION}.tar.gz Source1: named.sysconfig Source3: named.logrotate -Source4: named.NetworkManager Source7: bind-9.3.1rc1-sdb_tools-Makefile.in Source8: dnszone.schema Source12: README.sdb_pgsql Source25: named.conf.sample -Source28: config-13.tar.bz2 +Source28: config-14.tar.bz2 Source30: ldap2zone.c Source31: ldap2zone.1 Source32: named-sdb.8 @@ -58,6 +57,9 @@ Source44: named-chroot-setup.service Source45: named-sdb-chroot-setup.service Source46: named-setup-rndc.service Source47: named-pkcs11.service +# added due to GeoIP functionality tests +# patch tool does not support binary patches +Source48: geoip-testing-data.tar.xz # Common patches Patch5: bind-nonexec.patch @@ -104,7 +106,12 @@ Patch159:bind99-CVE-2015-5722.patch Patch160:bind99-CVE-2015-8000.patch Patch161:bind99-CVE-2015-8704.patch Patch162:bind99-CVE-2016-1285-CVE-2016-1286.patch -patch163:bind99-CVE-2016-2776.patch +Patch163:bind99-rh1291185.patch +Patch164:bind99-rh1259514.patch +Patch165:bind99-rh1306610.patch +Patch166:bind99-rh1220594-geoip.patch +Patch167:bind99-automatic-interface-scanning-rh1294506.patch +patch168:bind99-CVE-2016-2776.patch # Native PKCS#11 functionality from 9.10 Patch150:bind-9.9-allow_external_dnskey.patch @@ -144,7 +151,7 @@ Provides: caching-nameserver = 31:9.4.1-7.fc8 Obsoletes: dnssec-conf < 1.27-2 Provides: dnssec-conf = 1.27-1 BuildRequires: openssl-devel, libtool, autoconf, pkgconfig, libcap-devel -BuildRequires: libidn-devel, libxml2-devel +BuildRequires: libidn-devel, libxml2-devel, GeoIP-devel BuildRequires: systemd-units %if %{SDB} BuildRequires: openldap-devel, postgresql-devel, sqlite-devel, mysql-devel @@ -382,7 +389,17 @@ popd %patch160 -p1 -b .CVE-2015-8000 %patch161 -p1 -b .CVE-2015-8704 %patch162 -p1 -b .CVE-2016-1285-CVE-2016-1286 -%patch163 -p1 -b .CVE-2016-2776 +%patch163 -p1 -b .rh1291185 +%patch164 -p1 -b .rh1259514 +%patch165 -p1 -b .rh1306610-caa + +# GeoIP support +%patch166 -p1 -b .rh1220594-geoip +# extract the binary testing data +tar -xf %{SOURCE48} -C bin/tests/system/geoip/data + +%patch167 -p1 -b .rh1294506 +%patch168 -p1 -b .CVE-2016-2776 %if %{PKCS11} cp -r bin/named{,-pkcs11} @@ -453,6 +470,7 @@ libtoolize -c -f; aclocal -I libtool.m4 --force; autoconf -f --with-libtool \ --localstatedir=/var \ --enable-threads \ + --with-geoip \ --enable-ipv6 \ --enable-filter-aaaa \ --enable-rrl \ @@ -519,7 +537,7 @@ else rm -rf ${RPM_BUILD_ROOT} # Build directory hierarchy -mkdir -p ${RPM_BUILD_ROOT}/etc/{logrotate.d,NetworkManager/dispatcher.d} +mkdir -p ${RPM_BUILD_ROOT}/etc/logrotate.d mkdir -p ${RPM_BUILD_ROOT}%{_libdir}/bind mkdir -p ${RPM_BUILD_ROOT}/var/named/{slaves,data,dynamic} mkdir -p ${RPM_BUILD_ROOT}%{_mandir}/{man1,man5,man8} @@ -590,7 +608,6 @@ install -m 755 %{SOURCE41} ${RPM_BUILD_ROOT}%{_libexecdir}/setup-named-chroot.sh install -m 755 %{SOURCE42} ${RPM_BUILD_ROOT}%{_libexecdir}/generate-rndc-key.sh install -m 644 %SOURCE3 ${RPM_BUILD_ROOT}/etc/logrotate.d/named -install -m 755 %SOURCE4 ${RPM_BUILD_ROOT}/etc/NetworkManager/dispatcher.d/13-named mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/sysconfig install -m 644 %{SOURCE1} ${RPM_BUILD_ROOT}%{_sysconfdir}/sysconfig/named %if %{SDB} @@ -837,7 +854,6 @@ rm -rf ${RPM_BUILD_ROOT} %{_sysconfdir}/rwtab.d/named %{_unitdir}/named.service %{_unitdir}/named-setup-rndc.service -%{_sysconfdir}/NetworkManager/dispatcher.d/13-named %{_sbindir}/arpaname %{_sbindir}/ddns-confgen %{_sbindir}/genrandom @@ -1063,16 +1079,33 @@ rm -rf ${RPM_BUILD_ROOT} %endif %changelog -* Fri Sep 23 2016 Tomas Hozza - 32:9.9.4-29.4 +* Fri Sep 23 2016 Tomas Hozza - 32:9.9.4-37 - Fix CVE-2016-2776 -* Tue Mar 08 2016 Tomas Hozza - 32:9.9.4-29.3 +* Wed May 11 2016 Tomas Hozza - 32:9.9.4-36 +- Added automatic interface scan functionality (#1294506) +- Removed NetworkManager dispatcher script since it is not needed any more (#1294506) + +* Wed Apr 13 2016 Tomas Hozza - 32:9.9.4-35 +- Added GeoIP support (#1220594) + +* Fri Apr 01 2016 Tomas Hozza - 32:9.9.4-34 +- Added support for CAA records (#1306610) +- Use HTTPS URL instead of FTP for upstream sources (#1319280) + +* Tue Mar 22 2016 Tomas Hozza - 32:9.9.4-33 +- Fix excessive queries caused by DS chasing with stub zones when DNSSEC is not used (#1291185) +- Fix error in internal test suite (#1259514) +- Fix named-checkconf call in *-chroot.service files (#1278082) +- Fix incorrect path in BIND sample configuration and added comment to default configuration (#1247502) + +* Tue Mar 08 2016 Tomas Hozza - 32:9.9.4-32 - Fix CVE-2016-1285 and CVE-2016-1286 -* Mon Jan 18 2016 Tomas Hozza - 32:9.9.4-29.2 +* Mon Jan 18 2016 Tomas Hozza - 32:9.9.4-31 - Fix CVE-2015-8704 -* Mon Dec 14 2015 Tomas Hozza - 32:9.9.4-29.1 +* Mon Dec 14 2015 Tomas Hozza - 32:9.9.4-30 - Fix CVE-2015-8000 * Wed Sep 02 2015 Tomas Hozza - 32:9.9.4-29