From 27c44631f775defb217bb3409419371891ea03c1 Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Sun, 7 Jan 2018 18:45:58 +0200 Subject: [PATCH 1/6] lua-base4: Add newDRR for making DNSResourceRecords --- pdns/lua-base4.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pdns/lua-base4.cc b/pdns/lua-base4.cc index eb37dd92aa05..4ac452ab4d93 100644 --- a/pdns/lua-base4.cc +++ b/pdns/lua-base4.cc @@ -71,6 +71,18 @@ void BaseLua4::prepareContext() { d_lw->registerFunction("chopOff", [](DNSName&dn ) { return dn.chopOff(); }); // DNSResourceRecord + d_lw->writeFunction("newDRR", [](const DNSName& qname, const string& qtype, const unsigned int ttl, const string& content, boost::optional domain_id, boost::optional auth){ + auto drr = DNSResourceRecord(); + drr.qname = qname; + drr.qtype = qtype; + drr.ttl = ttl; + drr.setContent(content); + if (domain_id) + drr.domain_id = *domain_id; + if (auth) + drr.auth = *auth; + return drr; + }); d_lw->registerEqFunction(&DNSResourceRecord::operator==); d_lw->registerFunction("__lt", &DNSResourceRecord::operator<); d_lw->registerFunction("toString", [](const DNSResourceRecord& rec) { return rec.getZoneRepresentation();} ); From d45048a5c402615acec452ed03cdbea522b6ff3a Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Tue, 23 Jan 2018 13:52:19 +0200 Subject: [PATCH 2/6] lua-base4: Expose more DNSName methods These are needed to implement lua2 backend --- pdns/lua-base4.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pdns/lua-base4.cc b/pdns/lua-base4.cc index 4ac452ab4d93..e571304fdd1f 100644 --- a/pdns/lua-base4.cc +++ b/pdns/lua-base4.cc @@ -59,6 +59,9 @@ void BaseLua4::prepareContext() { // DNSName d_lw->writeFunction("newDN", [](const std::string& dom){ return DNSName(dom); }); + d_lw->registerFunction("__lt", &DNSName::operator<); + d_lw->registerFunction("canonCompare", &DNSName::canonCompare); + d_lw->registerFunction("makeRelative", &DNSName::makeRelative); d_lw->registerFunction("isPartOf", &DNSName::isPartOf); d_lw->registerFunction("countLabels", [](const DNSName& name) { return name.countLabels(); }); d_lw->registerFunction("wirelength", [](const DNSName& name) { return name.wirelength(); }); From 49f44df3aa54428a105a488f2e89ebf8313c4f10 Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Fri, 26 Jan 2018 14:51:34 +0200 Subject: [PATCH 3/6] lua-base4: Add QType methods --- pdns/lua-base4.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pdns/lua-base4.cc b/pdns/lua-base4.cc index e571304fdd1f..6e0e1e556804 100644 --- a/pdns/lua-base4.cc +++ b/pdns/lua-base4.cc @@ -144,6 +144,13 @@ void BaseLua4::prepareContext() { d_lw->registerFunction("check",[](const cas_t& cas, const ComboAddress&ca) { return cas.count(ca)>0; }); d_lw->registerFunction("equal", [](const ComboAddress& lhs, const ComboAddress& rhs) { return ComboAddress::addressOnlyEqual()(lhs, rhs); }); + // QType + d_lw->writeFunction("newQType", [](const string& s) { QType q; q = s; return q; }); + d_lw->registerFunction("getCode", &QType::getCode); + d_lw->registerFunction("getName", &QType::getName); + d_lw->registerEqFunction([](const QType& a, const QType& b){ return a == b;}); // operator overloading confuses LuaContext + d_lw->registerToStringFunction(&QType::getName); + // Netmask d_lw->writeFunction("newNetmask", [](const string& s) { return Netmask(s); }); d_lw->registerFunction("getNetwork", [](const Netmask& nm) { return nm.getNetwork(); } ); // const reference makes this necessary From 542febb3e0279bca6037d263aa9bc223f5a92876 Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Sun, 7 Jan 2018 20:53:06 +0200 Subject: [PATCH 4/6] pdns: Include lua-auth and it's dependencies in pdnsutil Needed by lua2 backend --- pdns/Makefile.am | 7 +++++++ pdns/pdnsutil.cc | 1 + 2 files changed, 8 insertions(+) diff --git a/pdns/Makefile.am b/pdns/Makefile.am index 746f9b951efa..90d31918af2c 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -305,6 +305,8 @@ pdnsutil_SOURCES = \ iputils.cc iputils.hh \ json.cc \ logger.cc \ + lua-auth4.cc lua-auth4.hh \ + lua-base4.cc lua-base4.hh \ misc.cc misc.hh \ nsecrecords.cc \ opensslsigners.cc opensslsigners.hh \ @@ -317,6 +319,7 @@ pdnsutil_SOURCES = \ sillyrecords.cc \ sstuff.hh \ statbag.cc \ + stubresolver.cc stubresolver.hh \ ueberbackend.cc \ unix_utility.cc \ zoneparser-tng.cc @@ -366,6 +369,10 @@ pdnsutil_SOURCES += pkcs11signers.cc pkcs11signers.hh pdnsutil_LDADD += $(P11KIT1_LIBS) endif +if LUA +pdnsutil_LDADD += $(LUA_LIBS) +endif + if GSS_TSIG pdnsutil_LDADD += $(GSS_LIBS) endif diff --git a/pdns/pdnsutil.cc b/pdns/pdnsutil.cc index b324b18235c5..cf8d7a32a227 100644 --- a/pdns/pdnsutil.cc +++ b/pdns/pdnsutil.cc @@ -80,6 +80,7 @@ void loadMainConfig(const std::string& configdir) string configname=::arg()["config-dir"]+"/"+s_programname+".conf"; cleanSlashes(configname); + ::arg().set("resolver","Use this resolver for ALIAS and the internal stub resolver")="no"; ::arg().set("default-ksk-algorithm","Default KSK algorithm")="ecdsa256"; ::arg().set("default-ksk-size","Default KSK size (0 means default)")="0"; ::arg().set("default-zsk-algorithm","Default ZSK algorithm")=""; From 63c1a37cd2e1a937bde3b01eab0be4056c350550 Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Sun, 7 Jan 2018 19:39:47 +0200 Subject: [PATCH 5/6] lua2backend: Add new backend This is API version 1 of lua2 backend. It provides improved interface for Lua script to act as backends. Configuration - `lua2-filename` - path to script - `lua2-query-logging` - log lua queries and results - `lua2-api' - API version (default 2) --- configure.ac | 5 + docs/backends/index.rst | 3 + docs/backends/lua2.rst | 188 ++++++++ modules/Makefile.am | 1 + modules/lua2backend/Makefile.am | 13 + modules/lua2backend/OBJECTFILES | 1 + modules/lua2backend/OBJECTLIBS | 1 + modules/lua2backend/lua2api2.cc | 30 ++ modules/lua2backend/lua2api2.hh | 418 ++++++++++++++++++ modules/lua2backend/lua2backend.cc | 73 +++ modules/lua2backend/lua2backend.hh | 30 ++ .../lua2backend/regression-tests/.gitignore | 3 + .../lua2backend/regression-tests/axfr/command | 2 + .../regression-tests/axfr/description | 1 + .../regression-tests/axfr/expected_result | 14 + .../axfr/expected_result.dnssec | 41 ++ .../regression-tests/basic-a-dnssec/command | 3 + .../basic-a-dnssec/description | 1 + .../basic-a-dnssec/expected_result | 5 + .../basic-a-dnssec/skip.nodnssec | 0 .../basic-a-resolution/command | 3 + .../basic-a-resolution/description | 2 + .../basic-a-resolution/expected_result | 3 + .../basic-aaaa-resolution/command | 3 + .../basic-aaaa-resolution/description | 2 + .../basic-aaaa-resolution/expected_result | 3 + .../regression-tests/lua2-dnssec.lua | 166 +++++++ modules/lua2backend/regression-tests/lua2.lua | 109 +++++ .../regression-tests/nsec-2-dnssec/command | 3 + .../nsec-2-dnssec/description | 1 + .../nsec-2-dnssec/expected_result | 9 + .../nsec-2-dnssec/skip.nodnssec | 0 .../regression-tests/nsec-dnssec/command | 3 + .../regression-tests/nsec-dnssec/description | 1 + .../nsec-dnssec/expected_result | 7 + .../nsec-dnssec/skip.nodnssec | 0 regression-tests/backends/common | 4 + regression-tests/backends/lua2-master | 40 ++ regression-tests/modules/liblua2backend.so | 1 + regression-tests/start-test-stop | 1 + 40 files changed, 1194 insertions(+) create mode 100644 docs/backends/lua2.rst create mode 100644 modules/lua2backend/Makefile.am create mode 100644 modules/lua2backend/OBJECTFILES create mode 100644 modules/lua2backend/OBJECTLIBS create mode 100644 modules/lua2backend/lua2api2.cc create mode 100644 modules/lua2backend/lua2api2.hh create mode 100644 modules/lua2backend/lua2backend.cc create mode 100644 modules/lua2backend/lua2backend.hh create mode 100644 modules/lua2backend/regression-tests/.gitignore create mode 100755 modules/lua2backend/regression-tests/axfr/command create mode 100644 modules/lua2backend/regression-tests/axfr/description create mode 100644 modules/lua2backend/regression-tests/axfr/expected_result create mode 100644 modules/lua2backend/regression-tests/axfr/expected_result.dnssec create mode 100755 modules/lua2backend/regression-tests/basic-a-dnssec/command create mode 100644 modules/lua2backend/regression-tests/basic-a-dnssec/description create mode 100644 modules/lua2backend/regression-tests/basic-a-dnssec/expected_result create mode 100644 modules/lua2backend/regression-tests/basic-a-dnssec/skip.nodnssec create mode 100755 modules/lua2backend/regression-tests/basic-a-resolution/command create mode 100644 modules/lua2backend/regression-tests/basic-a-resolution/description create mode 100644 modules/lua2backend/regression-tests/basic-a-resolution/expected_result create mode 100755 modules/lua2backend/regression-tests/basic-aaaa-resolution/command create mode 100644 modules/lua2backend/regression-tests/basic-aaaa-resolution/description create mode 100644 modules/lua2backend/regression-tests/basic-aaaa-resolution/expected_result create mode 100644 modules/lua2backend/regression-tests/lua2-dnssec.lua create mode 100644 modules/lua2backend/regression-tests/lua2.lua create mode 100755 modules/lua2backend/regression-tests/nsec-2-dnssec/command create mode 100644 modules/lua2backend/regression-tests/nsec-2-dnssec/description create mode 100644 modules/lua2backend/regression-tests/nsec-2-dnssec/expected_result create mode 100644 modules/lua2backend/regression-tests/nsec-2-dnssec/skip.nodnssec create mode 100755 modules/lua2backend/regression-tests/nsec-dnssec/command create mode 100644 modules/lua2backend/regression-tests/nsec-dnssec/description create mode 100644 modules/lua2backend/regression-tests/nsec-dnssec/expected_result create mode 100644 modules/lua2backend/regression-tests/nsec-dnssec/skip.nodnssec create mode 100644 regression-tests/backends/lua2-master create mode 120000 regression-tests/modules/liblua2backend.so diff --git a/configure.ac b/configure.ac index e03561e12935..022c43bbaec4 100644 --- a/configure.ac +++ b/configure.ac @@ -237,6 +237,10 @@ AM_CONDITIONAL([SQLITE3], [test "x$needsqlite3" = "xyes"]) for a in $modules; do AC_MSG_CHECKING([whether we can build module "${a}"]) + AS_IF([test "x$a" = "xlua2"], [ + AS_IF([test "x$with_lua" != "xyes"], + AC_MSG_ERROR([Cannot build lua2 module without lua]),[]) + ]) if [[ -d "$srcdir/modules/${a}backend" ]]; then AC_MSG_RESULT([yes]) moduledirs="$moduledirs ${a}backend" @@ -314,6 +318,7 @@ AC_CONFIG_FILES([ modules/gsqlite3backend/Makefile modules/ldapbackend/Makefile modules/luabackend/Makefile + modules/lua2backend/Makefile modules/mydnsbackend/Makefile modules/opendbxbackend/Makefile modules/oraclebackend/Makefile diff --git a/docs/backends/index.rst b/docs/backends/index.rst index 986ea0fb8c07..caa25276aa2a 100644 --- a/docs/backends/index.rst +++ b/docs/backends/index.rst @@ -22,6 +22,8 @@ The following table describes the supported backends and some of their capabilit +------------------------------------------------+--------+--------+-------+--------------+-------------+---------------------------------+--------------+ | :doc:`LDAP ` | Yes | No | No | No | No | No | ``ldap`` | +------------------------------------------------+--------+--------+-------+--------------+-------------+---------------------------------+--------------+ +| :doc:`Lua2 ` | Yes | Yes | No | No | Yes | Yes | ``lua2`` | ++------------------------------------------------+--------+--------+-------+--------------+-------------+---------------------------------+--------------+ | :doc:`MyDNS ` | Yes | No | No | No | No | No | ``mydns`` | +------------------------------------------------+--------+--------+-------+--------------+-------------+---------------------------------+--------------+ | :doc:`OpenDBX ` | Yes | Yes | Yes | Yes | No | No | ``opendbx`` | @@ -53,6 +55,7 @@ These backends have :doc:`features unique ` to the generic SQL back geoip ldap lua + lua2 mydns opendbx oracle diff --git a/docs/backends/lua2.rst b/docs/backends/lua2.rst new file mode 100644 index 000000000000..9725c8e54e88 --- /dev/null +++ b/docs/backends/lua2.rst @@ -0,0 +1,188 @@ +Lua Backend +=========== + +* Native: Yes +* Master: Yes +* Slave: No +* Superslave: No +* Autoserial: No +* DNSSEC: Yes +* Disabled data: No +* Comments: No +* Module name: lua2 +* Launch name: ``lua2`` + +This is a rewrite of existing Lua backend. +This backend is stub between your Lua script and PowerDNS authoritative server. +The backend uses AuthLua4 base class, and you can use same functions and types as in any other Lua script. + +.. warning:: + Some of the function calls and configuration settings have been changed from original ``Luabackend``, please review this document carefully. + +.. warning:: + All places which use DNS names now use DNSName class which cannot be compared directly to a string. + To compare them against a string use either ``tostring(dnsname)`` or ``newDN(string)``. + +.. warning:: + There is no API version 1. + Use Luabackend if you need version 1. + +API description (v2) +^^^^^^^^^^^^^^^^^^^^ + +``bool dns_dnssec`` +~~~~~~~~~~~~~~~~~~~ +If your script supports DNSSEC, set this to true. + +``dns_lookup(qtype, qname, domain_id, ctx)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Perform lookup of given resource record name and type. + +INPUT: + - QType qtype - Type of queried resource record + - DNSName qname - Name of queried resource record + - int domain_id - ID of associated domain + - table ctx - Query context table, contains ``source_address`` and ``real_source_address``. + +OUTPUT: + Expects a array which has tables with following keys: + - DNSName name - resource record name (can also be string) + - string type - type of resource record (can also be QType or valid integer) + - string content - resource record content + - int ttl - time to live for this resource record (default: configured value) + - int domain_id - ID of associated domain (default: -1) + - bool auth - Whether data is authoritative or not (default: true) + - int last_modified - UNIX timestamp of last modification + - int scope_mask - How many bytes of source IP netmask was used for this result + +NOTES: + Defaults are used for omitted keys. + Return empty array if you have no results. + The requested record type is unlikely to match what was asked from PowerDNS. + This function is **required**. + + +``dns_list(target, domain_id)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +List all resource records for target. + +INPUT: + - DNSName target - Zone name to list + - int domain_id - Associated domain ID + +OUTPUT: + Same as ``lookup`` function. Return false if not found or wanted. + +NOTES: + This function is **optional**. + +``dns_get_domaininfo(domain)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Get domain information for given domain. + +INPUT: + - DNSName domain - Domain to get info for + +OUTPUT: + Return false if not supported or found, otherwise expects a table with keys: + - string account - Associated account of this domain (default: ) + - string kind - Domain kind (NATIVE,MASTER,SLAVE) (default: NATIVE) + - int id - Associated domain ID (default: -1) + - int last_check - UNIX timestamp of last check from master (default: 0) + - table of strings masters - Master servers for this domain (default: ) + - long notified_serial - Notified serial to slaves (default: 0) + - long serial - Current domain serial + +NOTES: + This function is **optional**. + Defaults are used for omitted keys. + ``last_check`` is for automatic serial. + ``masters``, ``account``, ``notified_serial`` are for master/slave interaction only. + If this function is missing, it will revert into looking up SOA record for the given domain, + and uses that, if found. + +``dns_get_all_domains()`` +~~~~~~~~~~~~~~~~~~~~~~~~~ +Get domain information for all domains. + +OUTPUT: + Return false if not supported or found, otherwise return a table of string, domaininfo. See ``dns_get_domaininfo```. + +NOTES: + This function is **optional**, except if you need master functionality. + +``dns_get_domain_metadata(domain, kind)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Get metadata value(s) for given domain and metadata kind. + +INPUT: + - DNSName domain - Domain to get metadata for + - string kind - What kind of metadata to return + +OUTPUT: + - array of strings. Or false if not supported or found. + +NOTES: + This function is **required** if ``dns_dnssec`` is true. + +``dns_get_all_domain_metadata(domain)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Get all metadata for domain. + +INPUT: + - DNSName domain - Domain to get metadata for + +OUTPUT: + Table with metadata keys containing array of strings. Or false if not supported or found. + +NOTES: + This function is **optional**. + +``dns_get_domain_keys(domain)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Get DNSSEC key(s) for the given domain. Content must be valid key record in format that PowerDNS understands. + +INPUT: + - DNSName domain - Domain to get key(s) for + +OUTPUT: + Return false if not found or supported, otherwise expects array of tables with keys: + - int id - Key ID + - int flags - Key flags + - bool active - Is key active + - string content - Key itself + +NOTES: + This function is **optional**. However, not implementing this means you cannot do live signing. + +``dns_get_before_and_after_names_absolute(id, qname)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Calculate NSEC before/after value for the given qname for domain with id. + +INPUT: + - int id - Associated domain id + - DNSName qname - DNS name to calculate + +OUTPUT: + Table with keys: + - unhashed - DNSName of the unhashed relative to domain + - before - (hashed) name of previous record relative to domain + - after - (hashed) name of next record relative to domain + +NOTES: + Strings are promoted to DNSNames (you can also return DNSNames directly) + This function is **required** if ``dns_dnssec`` is true. + Hashing is required with NSEC3/5. + ``before`` and ``after`` should wrap, so that after record of last record is apex record. + You can use ``DNSName#canonCompare`` to sort records in correct order. + +``dns_set_notified(id, serial)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Called after NOTIFY so that backend can store the notified serial. + +INPUT: + - int id - Associated domain id + - long serial - Notified serial + +NOTES: + This function is **optional**. However, not implementing this can cause problems with master functionality. diff --git a/modules/Makefile.am b/modules/Makefile.am index fa231a03cafe..a5da8a5a65e6 100644 --- a/modules/Makefile.am +++ b/modules/Makefile.am @@ -10,6 +10,7 @@ DIST_SUBDIRS = \ gsqlite3backend \ ldapbackend \ luabackend \ + lua2backend \ mydnsbackend \ opendbxbackend \ oraclebackend \ diff --git a/modules/lua2backend/Makefile.am b/modules/lua2backend/Makefile.am new file mode 100644 index 000000000000..841abe3a07a3 --- /dev/null +++ b/modules/lua2backend/Makefile.am @@ -0,0 +1,13 @@ +AM_CPPFLAGS += $(LUA_CFLAGS) \ + -I$(top_srcdir)/ext/luawrapper/include + +EXTRA_DIST = OBJECTFILES OBJECTLIBS + +pkglib_LTLIBRARIES = liblua2backend.la + +liblua2backend_la_SOURCES = \ + lua2backend.cc lua2backend.hh \ + lua2api2.hh lua2api2.cc + +liblua2backend_la_LDFLAGS = -module -avoid-version +liblua2backend_la_LIBADD = $(LUA_LIBS) diff --git a/modules/lua2backend/OBJECTFILES b/modules/lua2backend/OBJECTFILES new file mode 100644 index 000000000000..79d15f2b15f2 --- /dev/null +++ b/modules/lua2backend/OBJECTFILES @@ -0,0 +1 @@ +lua2backend.lo lua2api2.lo diff --git a/modules/lua2backend/OBJECTLIBS b/modules/lua2backend/OBJECTLIBS new file mode 100644 index 000000000000..9094a029cd70 --- /dev/null +++ b/modules/lua2backend/OBJECTLIBS @@ -0,0 +1 @@ +$(LUA_LIBS) diff --git a/modules/lua2backend/lua2api2.cc b/modules/lua2backend/lua2api2.cc new file mode 100644 index 000000000000..df53d46b37f7 --- /dev/null +++ b/modules/lua2backend/lua2api2.cc @@ -0,0 +1,30 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTAPILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "lua2backend.hh" + +Lua2BackendAPIv2::~Lua2BackendAPIv2() { + if (f_deinit) + f_deinit(); +} diff --git a/modules/lua2backend/lua2api2.hh b/modules/lua2backend/lua2api2.hh new file mode 100644 index 000000000000..21519ead767a --- /dev/null +++ b/modules/lua2backend/lua2api2.hh @@ -0,0 +1,418 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTAPILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#pragma once +#ifndef LUA2API_2_HH +#define LUA2API_2_HH 1 + +#include "boost/lexical_cast.hpp" +#include "boost/algorithm/string/join.hpp" +#include "pdns/arguments.hh" + +class Lua2BackendAPIv2 : public DNSBackend, AuthLua4 { +private: + typedef std::function init_call_t; + typedef std::function deinit_call_t; + + typedef std::vector > lookup_context_t; + + typedef std::vector > > > > lookup_result_t; + typedef std::function lookup_call_t; + + typedef boost::variant list_result_t; + typedef std::function list_call_t; + + typedef vector > > > domaininfo_result_t; + typedef boost::variant get_domaininfo_result_t; + typedef vector > get_all_domains_result_t; + typedef std::function get_domaininfo_call_t; + typedef std::function get_all_domains_call_t; + + typedef vector > domain_metadata_result_t; + typedef boost::variant get_domain_metadata_result_t; + typedef boost::variant > > get_all_domain_metadata_result_t; + typedef std::function get_domain_metadata_call_t; + typedef std::function get_all_domain_metadata_call_t; + + typedef vector > > keydata_result_t; + typedef boost::variant > > get_domain_keys_result_t; + typedef std::function get_domain_keys_call_t; + + typedef std::vector > > before_and_after_names_result_t; + typedef boost::variant get_before_and_after_names_absolute_result_t; + typedef std::function get_before_and_after_names_absolute_call_t; + + typedef std::function set_notified_call_t; + + typedef std::function direct_backend_cmd_call_t; +public: + Lua2BackendAPIv2(const string& suffix) { + setArgPrefix("lua2"+suffix); + d_debug_log = mustDo("query-logging"); + prepareContext(); + loadFile(getArg("filename")); + } + + ~Lua2BackendAPIv2(); + + #define logCall(func, var) { if (d_debug_log) { L<readVariable>("dns_lookup").get_value_or(0); + f_list = d_lw->readVariable>("dns_list").get_value_or(0); + f_get_all_domains = d_lw->readVariable>("dns_get_all_domains").get_value_or(0); + f_get_domaininfo = d_lw->readVariable>("dns_get_domaininfo").get_value_or(0); + f_get_domain_metadata = d_lw->readVariable>("dns_get_domain_metadata").get_value_or(0); + f_get_all_domain_metadata = d_lw->readVariable>("dns_get_all_domain_metadata").get_value_or(0); + f_get_domain_keys = d_lw->readVariable>("dns_get_domain_keys").get_value_or(0); + f_get_before_and_after_names_absolute = d_lw->readVariable>("dns_get_before_and_after_names_absolute").get_value_or(0); + f_set_notified = d_lw->readVariable>("dns_set_notified").get_value_or(0); + + auto init = d_lw->readVariable>("dns_init").get_value_or(0); + if (init) + init(); + + f_deinit = d_lw->readVariable>("dns_deinit").get_value_or(0); + + if (f_lookup == nullptr) + throw PDNSException("dns_lookup missing"); + + /* see if dnssec support is wanted */ + d_dnssec = d_lw->readVariable>("dns_dnssec").get_value_or(false); + if (d_dnssec) { + if (f_get_domain_metadata == nullptr) + throw PDNSException("dns_dnssec is true but dns_get_domain_metadata is missing"); + if (f_get_before_and_after_names_absolute == nullptr) + throw PDNSException("dns_dnssec is true but dns_get_before_and_after_names_absolute is missing"); + /* domain keys is not strictly speaking necessary for dnssec backend */ + if (f_get_domain_keys == nullptr) + L<(item.second)); + else if (item.second.which() == 3) + rec.qtype = boost::get(item.second); + else if (item.second.which() == 4) + rec.qtype = boost::get(item.second); + else + throw PDNSException("Unsupported value for type"); + } else if (item.first == "name") { + if (item.second.which() == 3) + rec.qname = DNSName(boost::get(item.second)); + else if (item.second.which() == 2) + rec.qname = boost::get(item.second); + else + throw PDNSException("Unsupported value for name"); + } else if (item.first == "domain_id") + rec.domain_id = boost::get(item.second); + else if (item.first == "auth") + rec.auth = boost::get(item.second); + else if (item.first == "last_modified") + rec.last_modified = static_cast(boost::get(item.second)); + else if (item.first == "ttl") + rec.ttl = boost::get(item.second); + else if (item.first == "content") + rec.setContent(boost::get(item.second)); + else if (item.first == "scopeMask") + rec.scopeMask = boost::get(item.second); + else + L<getRemote().toString()}); + ctx.emplace_back(lookup_context_t::value_type{"real_source_address", p->getRealRemote().toString()}); + } + + logCall("lookup", "qtype="<readVariable>(cmd).get_value_or(0); + if (f == nullptr) { + return cmd + "not found"; + } + logCall(cmd, "parameter="<(item.second); + else if (item.first == "last_check") + di.last_check = static_cast(boost::get(item.second)); + else if (item.first == "masters") + di.masters = boost::get>(item.second); + else if (item.first == "id") + di.id = static_cast(boost::get(item.second)); + else if (item.first == "notified_serial") + di.notified_serial = static_cast(boost::get(item.second)); + else if (item.first == "serial") + di.serial = static_cast(boost::get(item.second)); + else if (item.first == "kind") + di.kind = DomainInfo::stringToKind(boost::get(item.second)); + else + L<push_back(di); + } + } + + bool getAllDomainMetadata(const DNSName& name, std::map >& meta) override { + if (f_get_all_domain_metadata == nullptr) + return false; + + logCall("get_all_domain_metadata","name="< > >(result)) { + meta[row.first].clear(); + for(const auto& item: row.second) + meta[row.first].push_back(item.second); + logResult("kind="<& meta) override { + if (f_get_domain_metadata == nullptr) + return false; + + logCall("get_domain_metadata","name="<(result)) + meta.push_back(item.second); + + logResult("value="<& keys) override { + if (f_get_domain_keys == nullptr) + return false; + + logCall("get_domain_keys","name="< > >(result)) { + DNSBackend::KeyData key; + for(const auto& item: row.second) { + if (item.first == "content") + key.content = boost::get(item.second); + else if (item.first == "id") + key.id = static_cast(boost::get(item.second)); + else if (item.first == "flags") + key.flags = static_cast(boost::get(item.second)); + else if (item.first == "active") + key.active = boost::get(item.second); + else + L<(result); + if (row.size() != 3) { + L<(item.second)); + else + value = DNSName(boost::get(item.second)); + if (item.first == "unhashed") + unhashed = value; + else if (item.first == "before") + before = value; + else if (item.first == "after") + after = value; + else { + L< pdns-lua2.conf < Date: Tue, 23 Jan 2018 13:54:25 +0200 Subject: [PATCH 6/6] travis: Run tests for lua2 --- build-scripts/travis.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build-scripts/travis.sh b/build-scripts/travis.sh index 9b0ef4bd761e..a556f7cc1cb7 100755 --- a/build-scripts/travis.sh +++ b/build-scripts/travis.sh @@ -370,7 +370,7 @@ build_auth() { run "./bootstrap" # Build without --enable-botan, no botan 2.x in Travis CI run "CFLAGS='-O1' CXXFLAGS='-O1' ./configure \ - --with-dynmodules='bind gmysql geoip gpgsql gsqlite3 ldap lua mydns opendbx pipe random remote tinydns godbc' \ + --with-dynmodules='bind gmysql geoip gpgsql gsqlite3 ldap lua mydns opendbx pipe random remote tinydns godbc lua2' \ --with-modules='' \ --with-sqlite3 \ --enable-libsodium \ @@ -532,6 +532,9 @@ test_auth() { run "./timestamp ./start-test-stop 5300 gsqlite3-nsec3-optout-both" run "./timestamp ./start-test-stop 5300 gsqlite3-nsec3-narrow" + run "./timestamp ./start-test-stop 5300 lua2" + run "./timestamp ./start-test-stop 5300 lua2-dnssec" + run "cd .." ### api ###