]>
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 stubParseResolveConf();
48 d_lw
->writeFunction("resolve", [](const std::string
& qname
, uint16_t qtype
) {
49 std::vector
<DNSZoneRecord
> ret
;
50 std::unordered_map
<int, DNSResourceRecord
> luaResult
;
51 stubDoResolve(DNSName(qname
), qtype
, ret
);
53 for(const auto &row
: ret
) {
54 luaResult
[++i
] = DNSResourceRecord::fromWire(row
.dr
);
55 luaResult
[i
].auth
= row
.auth
;
61 d_lw
->writeFunction("newDNSPacket", [](bool isQuery
) { return new DNSPacket(isQuery
); });
62 d_lw
->writeFunction("dupDNSPacket", [](const DNSPacket
&orig
) { return new DNSPacket(orig
); });
63 d_lw
->registerFunction
<DNSPacket
, int(const char *, size_t)>("noparse", [](DNSPacket
&p
, const char *mesg
, size_t len
){ return p
.noparse(mesg
, len
); });
64 d_lw
->registerFunction
<DNSPacket
, int(const char *, size_t)>("parse", [](DNSPacket
&p
, const char *mesg
, size_t len
){ return p
.parse(mesg
, len
); });
65 d_lw
->registerFunction
<DNSPacket
, const std::string()>("getString", [](DNSPacket
&p
) { return p
.getString(); });
66 d_lw
->registerFunction
<DNSPacket
, void(const ComboAddress
&)>("setRemote", [](DNSPacket
&p
, const ComboAddress
&ca
) { p
.setRemote(&ca
); });
67 d_lw
->registerFunction
<DNSPacket
, ComboAddress()>("getRemote", [](DNSPacket
&p
) { return p
.getRemote(); });
68 d_lw
->registerFunction
<DNSPacket
, Netmask()>("getRealRemote", [](DNSPacket
&p
) { return p
.getRealRemote(); });
69 d_lw
->registerFunction
<DNSPacket
, ComboAddress()>("getLocal", [](DNSPacket
&p
) { return p
.getLocal(); });
70 d_lw
->registerFunction
<DNSPacket
, unsigned int()>("getRemotePort", [](DNSPacket
&p
) { return p
.getRemotePort(); });
71 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())); });
72 d_lw
->registerFunction
<DNSPacket
, void(bool)>("setA", [](DNSPacket
&p
, bool a
) { return p
.setA(a
); });
73 d_lw
->registerFunction
<DNSPacket
, void(unsigned int)>("setID", [](DNSPacket
&p
, unsigned int id
) { return p
.setID(static_cast<uint16_t>(id
)); });
74 d_lw
->registerFunction
<DNSPacket
, void(bool)>("setRA", [](DNSPacket
&p
, bool ra
) { return p
.setRA(ra
); });
75 d_lw
->registerFunction
<DNSPacket
, void(bool)>("setRD", [](DNSPacket
&p
, bool rd
) { return p
.setRD(rd
); });
76 d_lw
->registerFunction
<DNSPacket
, void(bool)>("setAnswer", [](DNSPacket
&p
, bool answer
) { return p
.setAnswer(answer
); });
77 d_lw
->registerFunction
<DNSPacket
, void(unsigned int)>("setOpCode", [](DNSPacket
&p
, unsigned int opcode
) { return p
.setOpcode(static_cast<uint16_t>(opcode
)); });
78 d_lw
->registerFunction
<DNSPacket
, void(int)>("setRcode", [](DNSPacket
&p
, int rcode
) { return p
.setRcode(rcode
); });
79 d_lw
->registerFunction
<DNSPacket
, void()>("clearRecords",[](DNSPacket
&p
){p
.clearRecords();});
80 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
); });
81 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
); }});
82 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())); });
83 d_lw
->registerFunction
<DNSPacket
, bool()>("isEmpty", [](DNSPacket
&p
){return p
.isEmpty();});
84 d_lw
->registerFunction
<DNSPacket
, DNSPacket
*()>("replyPacket",[](DNSPacket
& p
){ return p
.replyPacket();});
85 d_lw
->registerFunction
<DNSPacket
, bool()>("hasEDNSSubnet", [](DNSPacket
&p
){return p
.hasEDNSSubnet();});
86 d_lw
->registerFunction
<DNSPacket
, bool()>("hasEDNS",[](DNSPacket
&p
){return p
.hasEDNS();});
87 d_lw
->registerFunction
<DNSPacket
, unsigned int()>("getEDNSVersion",[](DNSPacket
&p
){return p
.getEDNSVersion();});
88 d_lw
->registerFunction
<DNSPacket
, void(unsigned int)>("setEDNSRcode",[](DNSPacket
&p
, unsigned int extRCode
){p
.setEDNSRcode(static_cast<uint16_t>(extRCode
));});
89 d_lw
->registerFunction
<DNSPacket
, unsigned int()>("getEDNSRcode",[](DNSPacket
&p
){return p
.getEDNSRCode();});
90 d_lw
->registerFunction
<DNSPacket
, DNSName()>("getTSIGKeyname",[](DNSPacket
&p
){ return p
.getTSIGKeyname();});
91 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
;});
92 d_lw
->registerMember
<DNSPacket
, DNSName
>("qdomain", [](const DNSPacket
&p
) -> DNSName
{ return p
.qdomain
; }, [](DNSPacket
&p
, const DNSName
& name
) { p
.qdomain
= name
; });
93 d_lw
->registerMember
<DNSPacket
, DNSName
>("qdomainwild", [](const DNSPacket
&p
) -> DNSName
{ return p
.qdomainwild
; }, [](DNSPacket
&p
, const DNSName
& name
) { p
.qdomainwild
= name
; });
94 d_lw
->registerMember
<DNSPacket
, DNSName
>("qdomainzone", [](const DNSPacket
&p
) -> DNSName
{ return p
.qdomainzone
; }, [](DNSPacket
&p
, const DNSName
& name
) { p
.qdomainzone
= name
; });
96 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
; });
97 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
; });
98 /* End of DNSPacket */
102 d_lw
->registerFunction
<DNSName(UpdatePolicyQuery::*)()>("getQName", [](UpdatePolicyQuery
& upq
) { return upq
.qname
; });
103 d_lw
->registerFunction
<DNSName(UpdatePolicyQuery::*)()>("getZoneName", [](UpdatePolicyQuery
& upq
) { return upq
.zonename
; });
104 d_lw
->registerFunction
<uint16_t(UpdatePolicyQuery::*)()>("getQType", [](UpdatePolicyQuery
& upq
) { return upq
.qtype
; });
105 d_lw
->registerFunction
<ComboAddress(UpdatePolicyQuery::*)()>("getLocal", [](UpdatePolicyQuery
& upq
) { return upq
.local
; });
106 d_lw
->registerFunction
<ComboAddress(UpdatePolicyQuery::*)()>("getRemote", [](UpdatePolicyQuery
& upq
) { return upq
.remote
; });
107 d_lw
->registerFunction
<Netmask(UpdatePolicyQuery::*)()>("getRealRemote", [](UpdatePolicyQuery
& upq
) { return upq
.realRemote
; });
108 d_lw
->registerFunction
<DNSName(UpdatePolicyQuery::*)()>("getTsigName", [](UpdatePolicyQuery
& upq
) { return upq
.tsigName
; });
109 d_lw
->registerFunction
<std::string(UpdatePolicyQuery::*)()>("getPeerPrincipal", [](UpdatePolicyQuery
& upq
) { return upq
.peerPrincipal
; });
110 /* end of update policy */
113 void AuthLua4::postLoad() {
114 d_update_policy
= d_lw
->readVariable
<boost::optional
<luacall_update_policy_t
>>("updatepolicy").get_value_or(0);
115 d_axfr_filter
= d_lw
->readVariable
<boost::optional
<luacall_axfr_filter_t
>>("axfrfilter").get_value_or(0);
116 d_prequery
= d_lw
->readVariable
<boost::optional
<luacall_prequery_t
>>("prequery").get_value_or(0);
119 bool AuthLua4::axfrfilter(const ComboAddress
& remote
, const DNSName
& zone
, const DNSResourceRecord
& in
, vector
<DNSResourceRecord
>& out
) {
120 luacall_axfr_filter_t::result_type ret
;
123 if (d_axfr_filter
== NULL
) return false;
125 ret
= d_axfr_filter(remote
, zone
, in
);
126 rcode
= std::get
<0>(ret
);
128 // no modification, handle normally
131 else if (rcode
== 0) {
132 // replace the matching record by the filtered record(s)
134 else if (rcode
== 1) {
135 // append the filtered record(s) after the matching record
139 throw PDNSException("Cannot understand return code "+std::to_string(rcode
)+" in axfr filter response");
141 const auto& rows
= std::get
<1>(ret
);
143 for(const auto& row
: rows
) {
144 DNSResourceRecord rec
;
145 for(const auto& col
: row
.second
) {
146 if (col
.first
== "qtype")
147 rec
.qtype
= QType(boost::get
<unsigned int>(col
.second
));
148 else if (col
.first
== "qname")
149 rec
.qname
= DNSName(boost::get
<std::string
>(col
.second
)).makeLowerCase();
150 else if (col
.first
== "ttl")
151 rec
.ttl
= boost::get
<unsigned int>(col
.second
);
152 else if (col
.first
== "content")
153 rec
.setContent(boost::get
<std::string
>(col
.second
));
155 throw PDNSException("Cannot understand "+col
.first
+" in axfr filter response on row "+std::to_string(row
.first
));
164 bool AuthLua4::updatePolicy(const DNSName
&qname
, QType qtype
, const DNSName
&zonename
, DNSPacket
*packet
) {
165 // default decision is all goes
166 if (d_update_policy
== NULL
) return true;
168 UpdatePolicyQuery upq
;
170 upq
.qtype
= qtype
.getCode();
171 upq
.zonename
= zonename
;
172 upq
.local
= packet
->getLocal();
173 upq
.remote
= packet
->getRemote();
174 upq
.realRemote
= packet
->getRealRemote();
175 upq
.tsigName
= packet
->getTSIGKeyname();
176 upq
.peerPrincipal
= packet
->d_peer_principal
;
178 return d_update_policy(upq
);
181 DNSPacket
*AuthLua4::prequery(DNSPacket
*q
) {
182 if (d_prequery
== NULL
) return NULL
;
184 DNSPacket
*r
= q
->replyPacket();
191 AuthLua4::~AuthLua4() { }