]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/lua-auth4.cc
1 #include "lua-auth4.hh"
2 #include "stubresolver.hh"
5 #include "dnsparser.hh"
6 #include "namespaces.hh"
7 #include "ednssubnet.hh"
8 #include <unordered_set>
10 AuthLua4::AuthLua4() { prepareContext(); }
12 #if !defined(HAVE_LUA)
14 bool AuthLua4::updatePolicy(const DNSName
&qname
, QType qtype
, const DNSName
&zonename
, DNSPacket
*packet
) { return false; }
15 bool AuthLua4::axfrfilter(const ComboAddress
& remote
, const DNSName
& zone
, const DNSResourceRecord
& in
, vector
<DNSResourceRecord
>& out
) { return false; }
16 DNSPacket
*AuthLua4::prequery(DNSPacket
*q
) { return NULL
; }
18 AuthLua4::~AuthLua4() { }
20 void AuthLua4::postPrepareContext()
24 void AuthLua4::postLoad()
30 #include "ext/luawrapper/include/LuaContext.hpp"
32 void AuthLua4::postPrepareContext() {
33 stubParseResolveConf();
35 d_lw
->writeFunction("resolve", [](const std::string
& qname
, uint16_t qtype
) {
36 std::vector
<DNSZoneRecord
> ret
;
37 std::unordered_map
<int, DNSResourceRecord
> luaResult
;
38 stubDoResolve(DNSName(qname
), qtype
, ret
);
40 for(const auto &row
: ret
) {
41 luaResult
[++i
] = DNSResourceRecord::fromWire(row
.dr
);
42 luaResult
[i
].auth
= row
.auth
;
48 d_lw
->writeFunction("newDNSPacket", [](bool isQuery
) { return new DNSPacket(isQuery
); });
49 d_lw
->writeFunction("dupDNSPacket", [](const DNSPacket
&orig
) { return new DNSPacket(orig
); });
50 d_lw
->registerFunction
<DNSPacket
, int(const char *, size_t)>("noparse", [](DNSPacket
&p
, const char *mesg
, size_t len
){ return p
.noparse(mesg
, len
); });
51 d_lw
->registerFunction
<DNSPacket
, int(const char *, size_t)>("parse", [](DNSPacket
&p
, const char *mesg
, size_t len
){ return p
.parse(mesg
, len
); });
52 d_lw
->registerFunction
<DNSPacket
, const std::string()>("getString", [](DNSPacket
&p
) { return p
.getString(); });
53 d_lw
->registerFunction
<DNSPacket
, void(const ComboAddress
&)>("setRemote", [](DNSPacket
&p
, const ComboAddress
&ca
) { p
.setRemote(&ca
); });
54 d_lw
->registerFunction
<DNSPacket
, ComboAddress()>("getRemote", [](DNSPacket
&p
) { return p
.getRemote(); });
55 d_lw
->registerFunction
<DNSPacket
, Netmask()>("getRealRemote", [](DNSPacket
&p
) { return p
.getRealRemote(); });
56 d_lw
->registerFunction
<DNSPacket
, ComboAddress()>("getLocal", [](DNSPacket
&p
) { return p
.getLocal(); });
57 d_lw
->registerFunction
<DNSPacket
, unsigned int()>("getRemotePort", [](DNSPacket
&p
) { return p
.getRemotePort(); });
58 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())); });
59 d_lw
->registerFunction
<DNSPacket
, void(bool)>("setA", [](DNSPacket
&p
, bool a
) { return p
.setA(a
); });
60 d_lw
->registerFunction
<DNSPacket
, void(unsigned int)>("setID", [](DNSPacket
&p
, unsigned int id
) { return p
.setID(static_cast<uint16_t>(id
)); });
61 d_lw
->registerFunction
<DNSPacket
, void(bool)>("setRA", [](DNSPacket
&p
, bool ra
) { return p
.setRA(ra
); });
62 d_lw
->registerFunction
<DNSPacket
, void(bool)>("setRD", [](DNSPacket
&p
, bool rd
) { return p
.setRD(rd
); });
63 d_lw
->registerFunction
<DNSPacket
, void(bool)>("setAnswer", [](DNSPacket
&p
, bool answer
) { return p
.setAnswer(answer
); });
64 d_lw
->registerFunction
<DNSPacket
, void(unsigned int)>("setOpCode", [](DNSPacket
&p
, unsigned int opcode
) { return p
.setOpcode(static_cast<uint16_t>(opcode
)); });
65 d_lw
->registerFunction
<DNSPacket
, void(int)>("setRcode", [](DNSPacket
&p
, int rcode
) { return p
.setRcode(rcode
); });
66 d_lw
->registerFunction
<DNSPacket
, void()>("clearRecords",[](DNSPacket
&p
){p
.clearRecords();});
67 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
); });
68 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
); }});
69 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())); });
70 d_lw
->registerFunction
<DNSPacket
, bool()>("isEmpty", [](DNSPacket
&p
){return p
.isEmpty();});
71 d_lw
->registerFunction
<DNSPacket
, DNSPacket
*()>("replyPacket",[](DNSPacket
& p
){ return p
.replyPacket();});
72 d_lw
->registerFunction
<DNSPacket
, bool()>("hasEDNSSubnet", [](DNSPacket
&p
){return p
.hasEDNSSubnet();});
73 d_lw
->registerFunction
<DNSPacket
, bool()>("hasEDNS",[](DNSPacket
&p
){return p
.hasEDNS();});
74 d_lw
->registerFunction
<DNSPacket
, unsigned int()>("getEDNSVersion",[](DNSPacket
&p
){return p
.getEDNSVersion();});
75 d_lw
->registerFunction
<DNSPacket
, void(unsigned int)>("setEDNSRcode",[](DNSPacket
&p
, unsigned int extRCode
){p
.setEDNSRcode(static_cast<uint16_t>(extRCode
));});
76 d_lw
->registerFunction
<DNSPacket
, unsigned int()>("getEDNSRcode",[](DNSPacket
&p
){return p
.getEDNSRCode();});
77 d_lw
->registerFunction
<DNSPacket
, DNSName()>("getTSIGKeyname",[](DNSPacket
&p
){ return p
.getTSIGKeyname();});
78 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
;});
79 d_lw
->registerMember
<DNSPacket
, DNSName
>("qdomain", [](const DNSPacket
&p
) -> DNSName
{ return p
.qdomain
; }, [](DNSPacket
&p
, const DNSName
& name
) { p
.qdomain
= name
; });
80 d_lw
->registerMember
<DNSPacket
, DNSName
>("qdomainwild", [](const DNSPacket
&p
) -> DNSName
{ return p
.qdomainwild
; }, [](DNSPacket
&p
, const DNSName
& name
) { p
.qdomainwild
= name
; });
81 d_lw
->registerMember
<DNSPacket
, DNSName
>("qdomainzone", [](const DNSPacket
&p
) -> DNSName
{ return p
.qdomainzone
; }, [](DNSPacket
&p
, const DNSName
& name
) { p
.qdomainzone
= name
; });
83 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
; });
84 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
; });
85 /* End of DNSPacket */
89 d_lw
->registerFunction
<DNSName(UpdatePolicyQuery::*)()>("getQName", [](UpdatePolicyQuery
& upq
) { return upq
.qname
; });
90 d_lw
->registerFunction
<DNSName(UpdatePolicyQuery::*)()>("getZoneName", [](UpdatePolicyQuery
& upq
) { return upq
.zonename
; });
91 d_lw
->registerFunction
<uint16_t(UpdatePolicyQuery::*)()>("getQType", [](UpdatePolicyQuery
& upq
) { return upq
.qtype
; });
92 d_lw
->registerFunction
<ComboAddress(UpdatePolicyQuery::*)()>("getLocal", [](UpdatePolicyQuery
& upq
) { return upq
.local
; });
93 d_lw
->registerFunction
<ComboAddress(UpdatePolicyQuery::*)()>("getRemote", [](UpdatePolicyQuery
& upq
) { return upq
.remote
; });
94 d_lw
->registerFunction
<Netmask(UpdatePolicyQuery::*)()>("getRealRemote", [](UpdatePolicyQuery
& upq
) { return upq
.realRemote
; });
95 d_lw
->registerFunction
<DNSName(UpdatePolicyQuery::*)()>("getTsigName", [](UpdatePolicyQuery
& upq
) { return upq
.tsigName
; });
96 d_lw
->registerFunction
<std::string(UpdatePolicyQuery::*)()>("getPeerPrincipal", [](UpdatePolicyQuery
& upq
) { return upq
.peerPrincipal
; });
97 /* end of update policy */
100 void AuthLua4::postLoad() {
101 d_update_policy
= d_lw
->readVariable
<boost::optional
<luacall_update_policy_t
>>("updatepolicy").get_value_or(0);
102 d_axfr_filter
= d_lw
->readVariable
<boost::optional
<luacall_axfr_filter_t
>>("axfrfilter").get_value_or(0);
103 d_prequery
= d_lw
->readVariable
<boost::optional
<luacall_prequery_t
>>("prequery").get_value_or(0);
107 bool AuthLua4::axfrfilter(const ComboAddress
& remote
, const DNSName
& zone
, const DNSResourceRecord
& in
, vector
<DNSResourceRecord
>& out
) {
108 luacall_axfr_filter_t::result_type ret
;
111 if (d_axfr_filter
== NULL
) return false;
113 ret
= d_axfr_filter(remote
, zone
, in
);
114 rcode
= std::get
<0>(ret
);
116 // no modification, handle normally
119 else if (rcode
== 0) {
120 // replace the matching record by the filtered record(s)
122 else if (rcode
== 1) {
123 // append the filtered record(s) after the matching record
127 throw PDNSException("Cannot understand return code "+std::to_string(rcode
)+" in axfr filter response");
129 const auto& rows
= std::get
<1>(ret
);
131 for(const auto& row
: rows
) {
132 DNSResourceRecord rec
;
133 for(const auto& col
: row
.second
) {
134 if (col
.first
== "qtype")
135 rec
.qtype
= QType(boost::get
<unsigned int>(col
.second
));
136 else if (col
.first
== "qname")
137 rec
.qname
= DNSName(boost::get
<std::string
>(col
.second
)).makeLowerCase();
138 else if (col
.first
== "ttl")
139 rec
.ttl
= boost::get
<unsigned int>(col
.second
);
140 else if (col
.first
== "content")
141 rec
.setContent(boost::get
<std::string
>(col
.second
));
143 throw PDNSException("Cannot understand "+col
.first
+" in axfr filter response on row "+std::to_string(row
.first
));
152 bool AuthLua4::updatePolicy(const DNSName
&qname
, QType qtype
, const DNSName
&zonename
, DNSPacket
*packet
) {
153 // default decision is all goes
154 if (d_update_policy
== NULL
) return true;
156 UpdatePolicyQuery upq
;
158 upq
.qtype
= qtype
.getCode();
159 upq
.zonename
= zonename
;
160 upq
.local
= packet
->getLocal();
161 upq
.remote
= packet
->getRemote();
162 upq
.realRemote
= packet
->getRealRemote();
163 upq
.tsigName
= packet
->getTSIGKeyname();
164 upq
.peerPrincipal
= packet
->d_peer_principal
;
166 return d_update_policy(upq
);
169 DNSPacket
*AuthLua4::prequery(DNSPacket
*q
) {
170 if (d_prequery
== NULL
) return NULL
;
172 DNSPacket
*r
= q
->replyPacket();
179 AuthLua4::~AuthLua4() { }