]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/lua-auth4.cc
rec: Only log qname parsing errors when 'log-common-errors' is set
[thirdparty/pdns.git] / pdns / lua-auth4.cc
CommitLineData
b7edebf8 1#include "config.h"
2#if defined(HAVE_LUA)
3#include "ext/luawrapper/include/LuaContext.hpp"
4#endif
0ecc1158
AT
5#include "lua-auth4.hh"
6#include "stubresolver.hh"
7#include <fstream>
8#include "logger.hh"
9#include "dnsparser.hh"
0ecc1158 10#include "namespaces.hh"
0ecc1158
AT
11#include "ednssubnet.hh"
12#include <unordered_set>
5dbd408c 13#include "sstuff.hh"
14#include <thread>
5f7d5c56 15#include <mutex>
b7edebf8 16
e24b5737 17#include "ueberbackend.hh"
b7edebf8 18
9694e14f 19AuthLua4::AuthLua4() { prepareContext(); }
70c21c40 20
0ecc1158
AT
21#if !defined(HAVE_LUA)
22
0ecc1158 23bool AuthLua4::updatePolicy(const DNSName &qname, QType qtype, const DNSName &zonename, DNSPacket *packet) { return false; }
66470601 24bool AuthLua4::axfrfilter(const ComboAddress& remote, const DNSName& zone, const DNSResourceRecord& in, vector<DNSResourceRecord>& out) { return false; }
4754223f 25LuaContext* AuthLua4::getLua() { return 0; }
7c99293d
AT
26DNSPacket *AuthLua4::prequery(DNSPacket *q) { return NULL; }
27
3ce6361c 28AuthLua4::~AuthLua4() { }
0ecc1158 29
4e6b74ff
RG
30void AuthLua4::postPrepareContext()
31{
32}
33
34void AuthLua4::postLoad()
35{
36}
37
0ecc1158
AT
38#else
39
4754223f 40LuaContext* AuthLua4::getLua()
41{
42 return d_lw.get();
43}
44
70c21c40 45void AuthLua4::postPrepareContext() {
0ecc1158 46 d_lw->writeFunction("resolve", [](const std::string& qname, uint16_t qtype) {
7e683fad 47 std::vector<DNSZoneRecord> ret;
0ecc1158 48 std::unordered_map<int, DNSResourceRecord> luaResult;
7e683fad 49 stubDoResolve(DNSName(qname), qtype, ret);
0ecc1158 50 int i = 0;
7e683fad 51 for(const auto &row: ret) {
6b04b4ad 52 luaResult[++i] = DNSResourceRecord::fromWire(row.dr);
7e683fad 53 luaResult[i].auth = row.auth;
54 }
0ecc1158
AT
55 return luaResult;
56 });
57
c9b3d131
AT
58/* DNSPacket */
59 d_lw->writeFunction("newDNSPacket", [](bool isQuery) { return new DNSPacket(isQuery); });
60 d_lw->writeFunction("dupDNSPacket", [](const DNSPacket &orig) { return new DNSPacket(orig); });
61 d_lw->registerFunction<DNSPacket, int(const char *, size_t)>("noparse", [](DNSPacket &p, const char *mesg, size_t len){ return p.noparse(mesg, len); });
62 d_lw->registerFunction<DNSPacket, int(const char *, size_t)>("parse", [](DNSPacket &p, const char *mesg, size_t len){ return p.parse(mesg, len); });
63 d_lw->registerFunction<DNSPacket, const std::string()>("getString", [](DNSPacket &p) { return p.getString(); });
64 d_lw->registerFunction<DNSPacket, void(const ComboAddress&)>("setRemote", [](DNSPacket &p, const ComboAddress &ca) { p.setRemote(&ca); });
65 d_lw->registerFunction<DNSPacket, ComboAddress()>("getRemote", [](DNSPacket &p) { return p.getRemote(); });
66 d_lw->registerFunction<DNSPacket, Netmask()>("getRealRemote", [](DNSPacket &p) { return p.getRealRemote(); });
67 d_lw->registerFunction<DNSPacket, ComboAddress()>("getLocal", [](DNSPacket &p) { return p.getLocal(); });
68 d_lw->registerFunction<DNSPacket, unsigned int()>("getRemotePort", [](DNSPacket &p) { return p.getRemotePort(); });
7c99293d 69 d_lw->registerFunction<DNSPacket, std::tuple<const std::string, unsigned int>()>("getQuestion", [](DNSPacket &p) { return std::make_tuple(p.qdomain.toString(), static_cast<unsigned int>(p.qtype.getCode())); });
c9b3d131
AT
70 d_lw->registerFunction<DNSPacket, void(bool)>("setA", [](DNSPacket &p, bool a) { return p.setA(a); });
71 d_lw->registerFunction<DNSPacket, void(unsigned int)>("setID", [](DNSPacket &p, unsigned int id) { return p.setID(static_cast<uint16_t>(id)); });
72 d_lw->registerFunction<DNSPacket, void(bool)>("setRA", [](DNSPacket &p, bool ra) { return p.setRA(ra); });
73 d_lw->registerFunction<DNSPacket, void(bool)>("setRD", [](DNSPacket &p, bool rd) { return p.setRD(rd); });
74 d_lw->registerFunction<DNSPacket, void(bool)>("setAnswer", [](DNSPacket &p, bool answer) { return p.setAnswer(answer); });
75 d_lw->registerFunction<DNSPacket, void(unsigned int)>("setOpCode", [](DNSPacket &p, unsigned int opcode) { return p.setOpcode(static_cast<uint16_t>(opcode)); });
76 d_lw->registerFunction<DNSPacket, void(int)>("setRcode", [](DNSPacket &p, int rcode) { return p.setRcode(rcode); });
77 d_lw->registerFunction<DNSPacket, void()>("clearRecords",[](DNSPacket &p){p.clearRecords();});
78 d_lw->registerFunction<DNSPacket, void(DNSRecord&, bool)>("addRecord", [](DNSPacket &p, DNSRecord &dr, bool auth) { DNSZoneRecord dzr; dzr.dr = dr; dzr.auth = auth; p.addRecord(dzr); });
79 d_lw->registerFunction<DNSPacket, void(const vector<pair<unsigned int, DNSRecord> >&)>("addRecords", [](DNSPacket &p, const vector<pair<unsigned int, DNSRecord> >& records){ for(const auto &dr: records){ DNSZoneRecord dzr; dzr.dr = std::get<1>(dr); dzr.auth = true; p.addRecord(dzr); }});
80 d_lw->registerFunction<DNSPacket, void(unsigned int, const DNSName&, const std::string&)>("setQuestion", [](DNSPacket &p, unsigned int opcode, const DNSName &name, const string &type){ QType qtype; qtype = type; p.setQuestion(static_cast<int>(opcode), name, static_cast<int>(qtype.getCode())); });
81 d_lw->registerFunction<DNSPacket, bool()>("isEmpty", [](DNSPacket &p){return p.isEmpty();});
82 d_lw->registerFunction<DNSPacket, DNSPacket*()>("replyPacket",[](DNSPacket& p){ return p.replyPacket();});
83 d_lw->registerFunction<DNSPacket, bool()>("hasEDNSSubnet", [](DNSPacket &p){return p.hasEDNSSubnet();});
84 d_lw->registerFunction<DNSPacket, bool()>("hasEDNS",[](DNSPacket &p){return p.hasEDNS();});
85 d_lw->registerFunction<DNSPacket, unsigned int()>("getEDNSVersion",[](DNSPacket &p){return p.getEDNSVersion();});
86 d_lw->registerFunction<DNSPacket, void(unsigned int)>("setEDNSRcode",[](DNSPacket &p, unsigned int extRCode){p.setEDNSRcode(static_cast<uint16_t>(extRCode));});
87 d_lw->registerFunction<DNSPacket, unsigned int()>("getEDNSRcode",[](DNSPacket &p){return p.getEDNSRCode();});
88 d_lw->registerFunction<DNSPacket, DNSName()>("getTSIGKeyname",[](DNSPacket &p){ return p.getTSIGKeyname();});
a370a30e 89 d_lw->registerFunction<DNSPacket, std::unordered_map<unsigned int, DNSRecord>()>("getRRS", [](DNSPacket &p){ std::unordered_map<unsigned int, DNSRecord> ret; unsigned int i = 0; for(const auto &rec: p.getRRS()) { ret.insert({i++, rec.dr}); } return ret;});
c9b3d131
AT
90 d_lw->registerMember<DNSPacket, DNSName>("qdomain", [](const DNSPacket &p) -> DNSName { return p.qdomain; }, [](DNSPacket &p, const DNSName& name) { p.qdomain = name; });
91 d_lw->registerMember<DNSPacket, DNSName>("qdomainwild", [](const DNSPacket &p) -> DNSName { return p.qdomainwild; }, [](DNSPacket &p, const DNSName& name) { p.qdomainwild = name; });
92 d_lw->registerMember<DNSPacket, DNSName>("qdomainzone", [](const DNSPacket &p) -> DNSName { return p.qdomainzone; }, [](DNSPacket &p, const DNSName& name) { p.qdomainzone = name; });
93
94 d_lw->registerMember<DNSPacket, std::string>("d_peer_principal", [](const DNSPacket &p) -> std::string { return p.d_peer_principal; }, [](DNSPacket &p, const std::string &princ) { p.d_peer_principal = princ; });
95 d_lw->registerMember<DNSPacket, const std::string>("qtype", [](const DNSPacket &p) -> const std::string { return p.qtype.getName(); }, [](DNSPacket &p, const std::string &type) { p.qtype = type; });
96/* End of DNSPacket */
97
66470601 98
0ecc1158
AT
99/* update policy */
100 d_lw->registerFunction<DNSName(UpdatePolicyQuery::*)()>("getQName", [](UpdatePolicyQuery& upq) { return upq.qname; });
101 d_lw->registerFunction<DNSName(UpdatePolicyQuery::*)()>("getZoneName", [](UpdatePolicyQuery& upq) { return upq.zonename; });
102 d_lw->registerFunction<uint16_t(UpdatePolicyQuery::*)()>("getQType", [](UpdatePolicyQuery& upq) { return upq.qtype; });
103 d_lw->registerFunction<ComboAddress(UpdatePolicyQuery::*)()>("getLocal", [](UpdatePolicyQuery& upq) { return upq.local; });
104 d_lw->registerFunction<ComboAddress(UpdatePolicyQuery::*)()>("getRemote", [](UpdatePolicyQuery& upq) { return upq.remote; });
105 d_lw->registerFunction<Netmask(UpdatePolicyQuery::*)()>("getRealRemote", [](UpdatePolicyQuery& upq) { return upq.realRemote; });
106 d_lw->registerFunction<DNSName(UpdatePolicyQuery::*)()>("getTsigName", [](UpdatePolicyQuery& upq) { return upq.tsigName; });
107 d_lw->registerFunction<std::string(UpdatePolicyQuery::*)()>("getPeerPrincipal", [](UpdatePolicyQuery& upq) { return upq.peerPrincipal; });
108/* end of update policy */
70c21c40 109}
0ecc1158 110
70c21c40 111void AuthLua4::postLoad() {
0ecc1158 112 d_update_policy = d_lw->readVariable<boost::optional<luacall_update_policy_t>>("updatepolicy").get_value_or(0);
66470601 113 d_axfr_filter = d_lw->readVariable<boost::optional<luacall_axfr_filter_t>>("axfrfilter").get_value_or(0);
7c99293d 114 d_prequery = d_lw->readVariable<boost::optional<luacall_prequery_t>>("prequery").get_value_or(0);
66470601
AT
115}
116
117bool AuthLua4::axfrfilter(const ComboAddress& remote, const DNSName& zone, const DNSResourceRecord& in, vector<DNSResourceRecord>& out) {
118 luacall_axfr_filter_t::result_type ret;
119 int rcode;
120
121 if (d_axfr_filter == NULL) return false;
122
123 ret = d_axfr_filter(remote, zone, in);
124 rcode = std::get<0>(ret);
8b0f2ac7
CHB
125 if (rcode < 0) {
126 // no modification, handle normally
66470601 127 return false;
8b0f2ac7
CHB
128 }
129 else if (rcode == 0) {
130 // replace the matching record by the filtered record(s)
131 }
132 else if (rcode == 1) {
133 // append the filtered record(s) after the matching record
66470601 134 out.push_back(in);
8b0f2ac7 135 }
66470601
AT
136 else
137 throw PDNSException("Cannot understand return code "+std::to_string(rcode)+" in axfr filter response");
138
139 const auto& rows = std::get<1>(ret);
140
141 for(const auto& row: rows) {
142 DNSResourceRecord rec;
143 for(const auto& col: row.second) {
144 if (col.first == "qtype")
145 rec.qtype = QType(boost::get<unsigned int>(col.second));
146 else if (col.first == "qname")
92c6c467 147 rec.qname = DNSName(boost::get<std::string>(col.second)).makeLowerCase();
66470601
AT
148 else if (col.first == "ttl")
149 rec.ttl = boost::get<unsigned int>(col.second);
150 else if (col.first == "content")
151 rec.setContent(boost::get<std::string>(col.second));
152 else
153 throw PDNSException("Cannot understand "+col.first+" in axfr filter response on row "+std::to_string(row.first));
154 }
155 out.push_back(rec);
156 }
157
158 return true;
0ecc1158
AT
159}
160
66470601 161
0ecc1158 162bool AuthLua4::updatePolicy(const DNSName &qname, QType qtype, const DNSName &zonename, DNSPacket *packet) {
3c21232b
AT
163 // default decision is all goes
164 if (d_update_policy == NULL) return true;
165
0ecc1158
AT
166 UpdatePolicyQuery upq;
167 upq.qname = qname;
168 upq.qtype = qtype.getCode();
169 upq.zonename = zonename;
170 upq.local = packet->getLocal();
171 upq.remote = packet->getRemote();
172 upq.realRemote = packet->getRealRemote();
173 upq.tsigName = packet->getTSIGKeyname();
174 upq.peerPrincipal = packet->d_peer_principal;
175
176 return d_update_policy(upq);
177}
178
7c99293d
AT
179DNSPacket *AuthLua4::prequery(DNSPacket *q) {
180 if (d_prequery == NULL) return NULL;
181
182 DNSPacket *r = q->replyPacket();
183 if (d_prequery(r))
184 return r;
185 delete r;
186 return NULL;
187}
188
3ce6361c
RG
189AuthLua4::~AuthLua4() { }
190
6b547a53 191
0ecc1158 192#endif