Line data Source code
1 : /*
2 : Minetest
3 : Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4 :
5 : This program is free software; you can redistribute it and/or modify
6 : it under the terms of the GNU Lesser General Public License as published by
7 : the Free Software Foundation; either version 2.1 of the License, or
8 : (at your option) any later version.
9 :
10 : This program is distributed in the hope that it will be useful,
11 : but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 : GNU Lesser General Public License for more details.
14 :
15 : You should have received a copy of the GNU Lesser General Public License along
16 : with this program; if not, write to the Free Software Foundation, Inc.,
17 : 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 : */
19 :
20 : #include "cpp_api/s_server.h"
21 : #include "cpp_api/s_internal.h"
22 : #include "common/c_converter.h"
23 :
24 0 : bool ScriptApiServer::getAuth(const std::string &playername,
25 : std::string *dst_password,
26 : std::set<std::string> *dst_privs)
27 : {
28 0 : SCRIPTAPI_PRECHECKHEADER
29 :
30 0 : getAuthHandler();
31 0 : lua_getfield(L, -1, "get_auth");
32 0 : if (lua_type(L, -1) != LUA_TFUNCTION)
33 0 : throw LuaError("Authentication handler missing get_auth");
34 0 : lua_pushstring(L, playername.c_str());
35 0 : if (lua_pcall(L, 1, 1, m_errorhandler))
36 0 : scriptError();
37 0 : lua_remove(L, -2); // Remove auth handler
38 :
39 : // nil = login not allowed
40 0 : if (lua_isnil(L, -1))
41 0 : return false;
42 0 : luaL_checktype(L, -1, LUA_TTABLE);
43 :
44 0 : std::string password;
45 0 : bool found = getstringfield(L, -1, "password", password);
46 0 : if (!found)
47 0 : throw LuaError("Authentication handler didn't return password");
48 0 : if (dst_password)
49 0 : *dst_password = password;
50 :
51 0 : lua_getfield(L, -1, "privileges");
52 0 : if (!lua_istable(L, -1))
53 0 : throw LuaError("Authentication handler didn't return privilege table");
54 0 : if (dst_privs)
55 0 : readPrivileges(-1, *dst_privs);
56 0 : lua_pop(L, 1);
57 :
58 0 : return true;
59 : }
60 :
61 0 : void ScriptApiServer::getAuthHandler()
62 : {
63 0 : lua_State *L = getStack();
64 :
65 0 : lua_getglobal(L, "core");
66 0 : lua_getfield(L, -1, "registered_auth_handler");
67 0 : if (lua_isnil(L, -1)){
68 0 : lua_pop(L, 1);
69 0 : lua_getfield(L, -1, "builtin_auth_handler");
70 : }
71 0 : lua_remove(L, -2); // Remove core
72 0 : if (lua_type(L, -1) != LUA_TTABLE)
73 0 : throw LuaError("Authentication handler table not valid");
74 0 : }
75 :
76 0 : void ScriptApiServer::readPrivileges(int index, std::set<std::string> &result)
77 : {
78 0 : lua_State *L = getStack();
79 :
80 0 : result.clear();
81 0 : lua_pushnil(L);
82 0 : if (index < 0)
83 0 : index -= 1;
84 0 : while (lua_next(L, index) != 0) {
85 : // key at index -2 and value at index -1
86 0 : std::string key = luaL_checkstring(L, -2);
87 0 : bool value = lua_toboolean(L, -1);
88 0 : if (value)
89 0 : result.insert(key);
90 : // removes value, keeps key for next iteration
91 0 : lua_pop(L, 1);
92 : }
93 0 : }
94 :
95 0 : void ScriptApiServer::createAuth(const std::string &playername,
96 : const std::string &password)
97 : {
98 0 : SCRIPTAPI_PRECHECKHEADER
99 :
100 0 : getAuthHandler();
101 0 : lua_getfield(L, -1, "create_auth");
102 0 : lua_remove(L, -2); // Remove auth handler
103 0 : if (lua_type(L, -1) != LUA_TFUNCTION)
104 0 : throw LuaError("Authentication handler missing create_auth");
105 0 : lua_pushstring(L, playername.c_str());
106 0 : lua_pushstring(L, password.c_str());
107 0 : if (lua_pcall(L, 2, 0, m_errorhandler))
108 0 : scriptError();
109 0 : }
110 :
111 0 : bool ScriptApiServer::setPassword(const std::string &playername,
112 : const std::string &password)
113 : {
114 0 : SCRIPTAPI_PRECHECKHEADER
115 :
116 0 : getAuthHandler();
117 0 : lua_getfield(L, -1, "set_password");
118 0 : lua_remove(L, -2); // Remove auth handler
119 0 : if (lua_type(L, -1) != LUA_TFUNCTION)
120 0 : throw LuaError("Authentication handler missing set_password");
121 0 : lua_pushstring(L, playername.c_str());
122 0 : lua_pushstring(L, password.c_str());
123 0 : if (lua_pcall(L, 2, 1, m_errorhandler))
124 0 : scriptError();
125 0 : return lua_toboolean(L, -1);
126 : }
127 :
128 0 : bool ScriptApiServer::on_chat_message(const std::string &name,
129 : const std::string &message)
130 : {
131 0 : SCRIPTAPI_PRECHECKHEADER
132 :
133 : // Get core.registered_on_chat_messages
134 0 : lua_getglobal(L, "core");
135 0 : lua_getfield(L, -1, "registered_on_chat_messages");
136 : // Call callbacks
137 0 : lua_pushstring(L, name.c_str());
138 0 : lua_pushstring(L, message.c_str());
139 0 : script_run_callbacks(L, 2, RUN_CALLBACKS_MODE_OR_SC);
140 0 : bool ate = lua_toboolean(L, -1);
141 0 : return ate;
142 : }
143 :
144 0 : void ScriptApiServer::on_shutdown()
145 : {
146 0 : SCRIPTAPI_PRECHECKHEADER
147 :
148 : // Get registered shutdown hooks
149 0 : lua_getglobal(L, "core");
150 0 : lua_getfield(L, -1, "registered_on_shutdown");
151 : // Call callbacks
152 0 : script_run_callbacks(L, 0, RUN_CALLBACKS_MODE_FIRST);
153 3 : }
154 :
|