]>
Commit | Line | Data |
---|---|---|
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 | 19 | AuthLua4::AuthLua4() { prepareContext(); } |
70c21c40 | 20 | |
0ecc1158 AT |
21 | #if !defined(HAVE_LUA) |
22 | ||
0ecc1158 | 23 | bool AuthLua4::updatePolicy(const DNSName &qname, QType qtype, const DNSName &zonename, DNSPacket *packet) { return false; } |
66470601 | 24 | bool AuthLua4::axfrfilter(const ComboAddress& remote, const DNSName& zone, const DNSResourceRecord& in, vector<DNSResourceRecord>& out) { return false; } |
4754223f | 25 | LuaContext* AuthLua4::getLua() { return 0; } |
7c99293d AT |
26 | DNSPacket *AuthLua4::prequery(DNSPacket *q) { return NULL; } |
27 | ||
3ce6361c | 28 | AuthLua4::~AuthLua4() { } |
0ecc1158 | 29 | |
4e6b74ff RG |
30 | void AuthLua4::postPrepareContext() |
31 | { | |
32 | } | |
33 | ||
34 | void AuthLua4::postLoad() | |
35 | { | |
36 | } | |
37 | ||
0ecc1158 AT |
38 | #else |
39 | ||
4754223f | 40 | LuaContext* AuthLua4::getLua() |
41 | { | |
42 | return d_lw.get(); | |
43 | } | |
44 | ||
70c21c40 | 45 | void 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 | 111 | void 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 | ||
117 | bool 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 | 162 | bool 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 |
179 | DNSPacket *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 |
189 | AuthLua4::~AuthLua4() { } |
190 | ||
6b547a53 | 191 | |
0ecc1158 | 192 | #endif |