]>
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() { }
23 #include "ext/luawrapper/include/LuaContext.hpp"
25 void AuthLua4::postPrepareContext() {
26 stubParseResolveConf();
28 d_lw
->writeFunction("resolve", [](const std::string
& qname
, uint16_t qtype
) {
29 std::vector
<DNSZoneRecord
> ret
;
30 std::unordered_map
<int, DNSResourceRecord
> luaResult
;
31 stubDoResolve(DNSName(qname
), qtype
, ret
);
33 for(const auto &row
: ret
) {
34 luaResult
[++i
] = DNSResourceRecord::fromWire(row
.dr
);
35 luaResult
[i
].auth
= row
.auth
;
41 d_lw
->writeFunction("newDNSPacket", [](bool isQuery
) { return new DNSPacket(isQuery
); });
42 d_lw
->writeFunction("dupDNSPacket", [](const DNSPacket
&orig
) { return new DNSPacket(orig
); });
43 d_lw
->registerFunction
<DNSPacket
, int(const char *, size_t)>("noparse", [](DNSPacket
&p
, const char *mesg
, size_t len
){ return p
.noparse(mesg
, len
); });
44 d_lw
->registerFunction
<DNSPacket
, int(const char *, size_t)>("parse", [](DNSPacket
&p
, const char *mesg
, size_t len
){ return p
.parse(mesg
, len
); });
45 d_lw
->registerFunction
<DNSPacket
, const std::string()>("getString", [](DNSPacket
&p
) { return p
.getString(); });
46 d_lw
->registerFunction
<DNSPacket
, void(const ComboAddress
&)>("setRemote", [](DNSPacket
&p
, const ComboAddress
&ca
) { p
.setRemote(&ca
); });
47 d_lw
->registerFunction
<DNSPacket
, ComboAddress()>("getRemote", [](DNSPacket
&p
) { return p
.getRemote(); });
48 d_lw
->registerFunction
<DNSPacket
, Netmask()>("getRealRemote", [](DNSPacket
&p
) { return p
.getRealRemote(); });
49 d_lw
->registerFunction
<DNSPacket
, ComboAddress()>("getLocal", [](DNSPacket
&p
) { return p
.getLocal(); });
50 d_lw
->registerFunction
<DNSPacket
, unsigned int()>("getRemotePort", [](DNSPacket
&p
) { return p
.getRemotePort(); });
51 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())); });
52 d_lw
->registerFunction
<DNSPacket
, void(bool)>("setA", [](DNSPacket
&p
, bool a
) { return p
.setA(a
); });
53 d_lw
->registerFunction
<DNSPacket
, void(unsigned int)>("setID", [](DNSPacket
&p
, unsigned int id
) { return p
.setID(static_cast<uint16_t>(id
)); });
54 d_lw
->registerFunction
<DNSPacket
, void(bool)>("setRA", [](DNSPacket
&p
, bool ra
) { return p
.setRA(ra
); });
55 d_lw
->registerFunction
<DNSPacket
, void(bool)>("setRD", [](DNSPacket
&p
, bool rd
) { return p
.setRD(rd
); });
56 d_lw
->registerFunction
<DNSPacket
, void(bool)>("setAnswer", [](DNSPacket
&p
, bool answer
) { return p
.setAnswer(answer
); });
57 d_lw
->registerFunction
<DNSPacket
, void(unsigned int)>("setOpCode", [](DNSPacket
&p
, unsigned int opcode
) { return p
.setOpcode(static_cast<uint16_t>(opcode
)); });
58 d_lw
->registerFunction
<DNSPacket
, void(int)>("setRcode", [](DNSPacket
&p
, int rcode
) { return p
.setRcode(rcode
); });
59 d_lw
->registerFunction
<DNSPacket
, void()>("clearRecords",[](DNSPacket
&p
){p
.clearRecords();});
60 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
); });
61 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
); }});
62 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())); });
63 d_lw
->registerFunction
<DNSPacket
, bool()>("isEmpty", [](DNSPacket
&p
){return p
.isEmpty();});
64 d_lw
->registerFunction
<DNSPacket
, DNSPacket
*()>("replyPacket",[](DNSPacket
& p
){ return p
.replyPacket();});
65 d_lw
->registerFunction
<DNSPacket
, bool()>("hasEDNSSubnet", [](DNSPacket
&p
){return p
.hasEDNSSubnet();});
66 d_lw
->registerFunction
<DNSPacket
, bool()>("hasEDNS",[](DNSPacket
&p
){return p
.hasEDNS();});
67 d_lw
->registerFunction
<DNSPacket
, unsigned int()>("getEDNSVersion",[](DNSPacket
&p
){return p
.getEDNSVersion();});
68 d_lw
->registerFunction
<DNSPacket
, void(unsigned int)>("setEDNSRcode",[](DNSPacket
&p
, unsigned int extRCode
){p
.setEDNSRcode(static_cast<uint16_t>(extRCode
));});
69 d_lw
->registerFunction
<DNSPacket
, unsigned int()>("getEDNSRcode",[](DNSPacket
&p
){return p
.getEDNSRCode();});
70 d_lw
->registerFunction
<DNSPacket
, DNSName()>("getTSIGKeyname",[](DNSPacket
&p
){ return p
.getTSIGKeyname();});
71 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
;});
72 d_lw
->registerMember
<DNSPacket
, DNSName
>("qdomain", [](const DNSPacket
&p
) -> DNSName
{ return p
.qdomain
; }, [](DNSPacket
&p
, const DNSName
& name
) { p
.qdomain
= name
; });
73 d_lw
->registerMember
<DNSPacket
, DNSName
>("qdomainwild", [](const DNSPacket
&p
) -> DNSName
{ return p
.qdomainwild
; }, [](DNSPacket
&p
, const DNSName
& name
) { p
.qdomainwild
= name
; });
74 d_lw
->registerMember
<DNSPacket
, DNSName
>("qdomainzone", [](const DNSPacket
&p
) -> DNSName
{ return p
.qdomainzone
; }, [](DNSPacket
&p
, const DNSName
& name
) { p
.qdomainzone
= name
; });
76 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
; });
77 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
; });
78 /* End of DNSPacket */
82 d_lw
->registerFunction
<DNSName(UpdatePolicyQuery::*)()>("getQName", [](UpdatePolicyQuery
& upq
) { return upq
.qname
; });
83 d_lw
->registerFunction
<DNSName(UpdatePolicyQuery::*)()>("getZoneName", [](UpdatePolicyQuery
& upq
) { return upq
.zonename
; });
84 d_lw
->registerFunction
<uint16_t(UpdatePolicyQuery::*)()>("getQType", [](UpdatePolicyQuery
& upq
) { return upq
.qtype
; });
85 d_lw
->registerFunction
<ComboAddress(UpdatePolicyQuery::*)()>("getLocal", [](UpdatePolicyQuery
& upq
) { return upq
.local
; });
86 d_lw
->registerFunction
<ComboAddress(UpdatePolicyQuery::*)()>("getRemote", [](UpdatePolicyQuery
& upq
) { return upq
.remote
; });
87 d_lw
->registerFunction
<Netmask(UpdatePolicyQuery::*)()>("getRealRemote", [](UpdatePolicyQuery
& upq
) { return upq
.realRemote
; });
88 d_lw
->registerFunction
<DNSName(UpdatePolicyQuery::*)()>("getTsigName", [](UpdatePolicyQuery
& upq
) { return upq
.tsigName
; });
89 d_lw
->registerFunction
<std::string(UpdatePolicyQuery::*)()>("getPeerPrincipal", [](UpdatePolicyQuery
& upq
) { return upq
.peerPrincipal
; });
90 /* end of update policy */
93 void AuthLua4::postLoad() {
94 d_update_policy
= d_lw
->readVariable
<boost::optional
<luacall_update_policy_t
>>("updatepolicy").get_value_or(0);
95 d_axfr_filter
= d_lw
->readVariable
<boost::optional
<luacall_axfr_filter_t
>>("axfrfilter").get_value_or(0);
96 d_prequery
= d_lw
->readVariable
<boost::optional
<luacall_prequery_t
>>("prequery").get_value_or(0);
100 bool AuthLua4::axfrfilter(const ComboAddress
& remote
, const DNSName
& zone
, const DNSResourceRecord
& in
, vector
<DNSResourceRecord
>& out
) {
101 luacall_axfr_filter_t::result_type ret
;
104 if (d_axfr_filter
== NULL
) return false;
106 ret
= d_axfr_filter(remote
, zone
, in
);
107 rcode
= std::get
<0>(ret
);
113 throw PDNSException("Cannot understand return code "+std::to_string(rcode
)+" in axfr filter response");
115 const auto& rows
= std::get
<1>(ret
);
117 for(const auto& row
: rows
) {
118 DNSResourceRecord rec
;
119 for(const auto& col
: row
.second
) {
120 if (col
.first
== "qtype")
121 rec
.qtype
= QType(boost::get
<unsigned int>(col
.second
));
122 else if (col
.first
== "qname")
123 rec
.qname
= DNSName(boost::get
<std::string
>(col
.second
)).makeLowerCase();
124 else if (col
.first
== "ttl")
125 rec
.ttl
= boost::get
<unsigned int>(col
.second
);
126 else if (col
.first
== "content")
127 rec
.setContent(boost::get
<std::string
>(col
.second
));
129 throw PDNSException("Cannot understand "+col
.first
+" in axfr filter response on row "+std::to_string(row
.first
));
138 bool AuthLua4::updatePolicy(const DNSName
&qname
, QType qtype
, const DNSName
&zonename
, DNSPacket
*packet
) {
139 // default decision is all goes
140 if (d_update_policy
== NULL
) return true;
142 UpdatePolicyQuery upq
;
144 upq
.qtype
= qtype
.getCode();
145 upq
.zonename
= zonename
;
146 upq
.local
= packet
->getLocal();
147 upq
.remote
= packet
->getRemote();
148 upq
.realRemote
= packet
->getRealRemote();
149 upq
.tsigName
= packet
->getTSIGKeyname();
150 upq
.peerPrincipal
= packet
->d_peer_principal
;
152 return d_update_policy(upq
);
155 DNSPacket
*AuthLua4::prequery(DNSPacket
*q
) {
156 if (d_prequery
== NULL
) return NULL
;
158 DNSPacket
*r
= q
->replyPacket();
165 AuthLua4::~AuthLua4() { }