]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/lua-auth.cc
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * In addition, for the avoidance of any doubt, permission is granted to
10 * link this program with OpenSSL and to (re)distribute the binaries
11 * produced as the result of such linking.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include "lua-auth.hh"
27 #if !defined(HAVE_LUA)
29 AuthLua::AuthLua(const std::string
&fname
)
35 DNSPacket
* AuthLua::prequery(DNSPacket
*p
)
45 /* Include the Lua API header files. */
58 #include "namespaces.hh"
60 AuthLua::AuthLua(const std::string
&fname
)
63 registerLuaDNSPacket();
64 pthread_mutex_init(&d_lock
,0);
72 static DNSPacket
* ldp_checkDNSPacket(lua_State
*L
) {
73 void *ud
= luaL_checkudata(L
, 1, "LuaDNSPacket");
74 luaL_argcheck(L
, ud
!= NULL
, 1, "`LuaDNSPacket' expected");
75 return ((LuaDNSPacket
*)ud
)->d_p
;
78 static int ldp_setRcode(lua_State
*L
) {
79 DNSPacket
*p
=ldp_checkDNSPacket(L
);
80 #if LUA_VERSION_NUM < 503
81 int rcode
= luaL_checkint(L
, 2);
83 int rcode
= (int)luaL_checkinteger(L
, 2);
89 static int ldp_getQuestion(lua_State
*L
) {
90 DNSPacket
*p
=ldp_checkDNSPacket(L
);
91 lua_pushstring(L
, p
->qdomain
.toString().c_str());
92 lua_pushnumber(L
, p
->qtype
.getCode());
96 static int ldp_getWild(lua_State
*L
) {
97 DNSPacket
*p
=ldp_checkDNSPacket(L
);
98 if(p
->qdomainwild
.empty())
101 lua_pushstring(L
, p
->qdomainwild
.toString().c_str());
105 static int ldp_getZone(lua_State
*L
) {
106 DNSPacket
*p
=ldp_checkDNSPacket(L
);
107 if(p
->qdomainzone
.empty())
110 lua_pushstring(L
, p
->qdomainzone
.toString().c_str());
114 static int ldp_addRecords(lua_State
*L
) {
115 DNSPacket
*p
=ldp_checkDNSPacket(L
);
116 vector
<DNSRecord
> rrs
;
117 popResourceRecordsTable(L
, DNSName("BOGUS"), rrs
);
118 for(const DNSRecord
& dr
: rrs
) {
121 dzr
.auth
=true; // LET'S HOPE THIS IS TRUE XXX
127 static int ldp_getRemote(lua_State
*L
) {
128 DNSPacket
*p
=ldp_checkDNSPacket(L
);
129 lua_pushstring(L
, p
->getRemote().toString().c_str());
133 static int ldp_getRemoteRaw(lua_State
*L
) {
134 DNSPacket
*p
=ldp_checkDNSPacket(L
);
135 const ComboAddress
& ca
=p
->getRemote();
136 if(ca
.sin4
.sin_family
== AF_INET
) {
137 lua_pushlstring(L
, (const char*)&ca
.sin4
.sin_addr
.s_addr
, 4);
140 lua_pushlstring(L
, (const char*)&ca
.sin6
.sin6_addr
.s6_addr
, 16);
145 static int ldp_getRcode(lua_State
*L
) {
146 DNSPacket
*p
=ldp_checkDNSPacket(L
);
147 lua_pushnumber(L
, p
->d
.rcode
);
151 static int ldp_getSize(lua_State
*L
) {
152 DNSPacket
*p
=ldp_checkDNSPacket(L
);
153 lua_pushnumber(L
, p
->getString().size());
157 static int ldp_getRRCounts(lua_State
*L
) {
158 DNSPacket
*p
=ldp_checkDNSPacket(L
);
159 lua_pushnumber(L
, ntohs(p
->d
.ancount
));
160 lua_pushnumber(L
, ntohs(p
->d
.nscount
));
161 lua_pushnumber(L
, ntohs(p
->d
.arcount
));
165 // these functions are used for PowerDNS recursor regression testing against auth,
166 // and for the Lua Policy Engine. The Lua 5.2 implementation is untested.
167 static const struct luaL_Reg ldp_methods
[] = {
168 {"setRcode", ldp_setRcode
},
169 {"getQuestion", ldp_getQuestion
},
170 {"getWild", ldp_getWild
},
171 {"getZone", ldp_getZone
},
172 {"addRecords", ldp_addRecords
},
173 {"getRemote", ldp_getRemote
},
174 {"getRemoteRaw", ldp_getRemoteRaw
},
175 {"getSize", ldp_getSize
},
176 {"getRRCounts", ldp_getRRCounts
},
177 {"getRcode", ldp_getRcode
},
181 #if LUA_VERSION_NUM < 502
182 void AuthLua::registerLuaDNSPacket(void) {
184 luaL_newmetatable(d_lua
, "LuaDNSPacket");
186 lua_pushstring(d_lua
, "__index");
187 lua_pushvalue(d_lua
, -2); /* pushes the metatable */
188 lua_settable(d_lua
, -3); /* metatable.__index = metatable */
190 luaL_openlib(d_lua
, NULL
, ldp_methods
, 0);
196 void AuthLua::registerLuaDNSPacket(void) {
198 luaL_newmetatable(d_lua
, "LuaDNSPacket");
200 lua_pushstring(d_lua
, "__index");
201 lua_pushvalue(d_lua
, -2); /* pushes the metatable */
202 lua_settable(d_lua
, -3); /* metatable.__index = metatable */
204 luaL_setfuncs(d_lua
, ldp_methods
, 0);
210 DNSPacket
* AuthLua::prequery(DNSPacket
*p
)
212 lua_getglobal(d_lua
,"prequery");
213 if(!lua_isfunction(d_lua
, -1)) {
214 // cerr<<"No such function 'prequery'\n";
220 // allocate a fresh packet and prefill the question
224 LuaDNSPacket
* lua_dp
= (LuaDNSPacket
*)lua_newuserdata(d_lua
, sizeof(LuaDNSPacket
));
227 // make it of the right type
228 luaL_getmetatable(d_lua
, "LuaDNSPacket");
229 lua_setmetatable(d_lua
, -2);
231 if(lua_pcall(d_lua
, 1, 1, 0)) { // error
232 string error
=string("lua error in prequery: ")+lua_tostring(d_lua
, -1);
233 theL()<<Logger::Error
<<error
<<endl
;
236 throw runtime_error(error
);
238 bool res
=lua_toboolean(d_lua
, 1);
241 // prequery created our response, use it
242 theL()<<Logger::Info
<<"overriding query from lua prequery result"<<endl
;
247 // prequery wanted nothing to do with this question