]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/lua-auth4.cc
3 #include "ext/luawrapper/include/LuaContext.hpp"
5 #include "lua-auth4.hh"
6 #include "stubresolver.hh"
9 #include "dnsparser.hh"
10 #include "namespaces.hh"
11 #include "ednssubnet.hh"
12 #include <unordered_set>
17 #include "ueberbackend.hh"
19 AuthLua4::AuthLua4() { prepareContext(); }
21 #if !defined(HAVE_LUA)
23 bool AuthLua4::updatePolicy(const DNSName
&qname
, QType qtype
, const DNSName
&zonename
, DNSPacket
*packet
) { return false; }
24 bool AuthLua4::axfrfilter(const ComboAddress
& remote
, const DNSName
& zone
, const DNSResourceRecord
& in
, vector
<DNSResourceRecord
>& out
) { return false; }
25 LuaContext
* AuthLua4::getLua() { return 0; }
26 DNSPacket
*AuthLua4::prequery(DNSPacket
*q
) { return NULL
; }
28 AuthLua4::~AuthLua4() { }
30 void AuthLua4::postPrepareContext()
34 void AuthLua4::postLoad()
40 LuaContext
* AuthLua4::getLua()
45 void AuthLua4::postPrepareContext() {
46 d_lw
->writeFunction("resolve", [](const std::string
& qname
, uint16_t qtype
) {
47 std::vector
<DNSZoneRecord
> ret
;
48 std::unordered_map
<int, DNSResourceRecord
> luaResult
;
49 stubDoResolve(DNSName(qname
), qtype
, ret
);
51 for(const auto &row
: ret
) {
52 luaResult
[++i
] = DNSResourceRecord::fromWire(row
.dr
);
53 luaResult
[i
].auth
= row
.auth
;
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(); });
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())); });
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();});
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
;});
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
; });
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 */
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 */
111 void AuthLua4::postLoad() {
112 d_update_policy
= d_lw
->readVariable
<boost::optional
<luacall_update_policy_t
>>("updatepolicy").get_value_or(0);
113 d_axfr_filter
= d_lw
->readVariable
<boost::optional
<luacall_axfr_filter_t
>>("axfrfilter").get_value_or(0);
114 d_prequery
= d_lw
->readVariable
<boost::optional
<luacall_prequery_t
>>("prequery").get_value_or(0);
117 bool AuthLua4::axfrfilter(const ComboAddress
& remote
, const DNSName
& zone
, const DNSResourceRecord
& in
, vector
<DNSResourceRecord
>& out
) {
118 luacall_axfr_filter_t::result_type ret
;
121 if (d_axfr_filter
== NULL
) return false;
123 ret
= d_axfr_filter(remote
, zone
, in
);
124 rcode
= std::get
<0>(ret
);
126 // no modification, handle normally
129 else if (rcode
== 0) {
130 // replace the matching record by the filtered record(s)
132 else if (rcode
== 1) {
133 // append the filtered record(s) after the matching record
137 throw PDNSException("Cannot understand return code "+std::to_string(rcode
)+" in axfr filter response");
139 const auto& rows
= std::get
<1>(ret
);
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")
147 rec
.qname
= DNSName(boost::get
<std::string
>(col
.second
)).makeLowerCase();
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
));
153 throw PDNSException("Cannot understand "+col
.first
+" in axfr filter response on row "+std::to_string(row
.first
));
162 bool AuthLua4::updatePolicy(const DNSName
&qname
, QType qtype
, const DNSName
&zonename
, DNSPacket
*packet
) {
163 // default decision is all goes
164 if (d_update_policy
== NULL
) return true;
166 UpdatePolicyQuery upq
;
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
;
176 return d_update_policy(upq
);
179 DNSPacket
*AuthLua4::prequery(DNSPacket
*q
) {
180 if (d_prequery
== NULL
) return NULL
;
182 DNSPacket
*r
= q
->replyPacket();
189 AuthLua4::~AuthLua4() { }