From 7cad0a2dcd817b179f82066964c45937a603d138 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Fri, 30 Mar 2012 18:42:18 +0300 Subject: Reimplement authentication handler in Lua; now we have 1) infinite privilege names, 2) minetest.register_authentication_handler() --- src/server.cpp | 178 +++++++++++++++++++-------------------------------------- 1 file changed, 58 insertions(+), 120 deletions(-) (limited to 'src/server.cpp') diff --git a/src/server.cpp b/src/server.cpp index 4a6165f30..e9b236cc4 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -142,6 +142,10 @@ void * ServerThread::Thread() { m_server->setAsyncFatalError(e.what()); } + catch(LuaError &e) + { + m_server->setAsyncFatalError(e.what()); + } } END_DEBUG_EXCEPTION_HANDLER(errorstream) @@ -905,7 +909,6 @@ Server::Server( m_async_fatal_error(""), m_env(NULL), m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, this), - m_authmanager(path_world+DIR_DELIM+"auth.txt"), m_banmanager(path_world+DIR_DELIM+"ipban.txt"), m_lua(NULL), m_itemdef(createItemDefManager()), @@ -1844,10 +1847,6 @@ void Server::AsyncRunStep() ScopeProfiler sp(g_profiler, "Server: saving stuff"); - // Auth stuff - if(m_authmanager.isModified()) - m_authmanager.save(); - //Ban stuff if(m_banmanager.isModified()) m_banmanager.save(); @@ -2083,34 +2082,30 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) password[PASSWORD_SIZE-1] = 0; } - // Add player to auth manager - if(m_authmanager.exists(playername) == false) - { - std::wstring default_password = + std::string checkpwd; + bool has_auth = scriptapi_get_auth(m_lua, playername, &checkpwd, NULL); + + if(!has_auth){ + std::wstring raw_default_password = narrow_to_wide(g_settings->get("default_password")); - std::string translated_default_password = - translatePassword(playername, default_password); + std::string use_password = + translatePassword(playername, raw_default_password); // If default_password is empty, allow any initial password - if (default_password.length() == 0) - translated_default_password = password; - - infostream<<"Server: adding player "<get("default_privs"))); - m_authmanager.save(); - } + if (raw_default_password.length() == 0) + use_password = password; - std::string checkpwd = m_authmanager.getPassword(playername); + scriptapi_create_auth(m_lua, playername, use_password); + } + + has_auth = scriptapi_get_auth(m_lua, playername, &checkpwd, NULL); - /*infostream<<"Server: Client gave password '"<= g_settings->getU16("max_users") && - (m_authmanager.getPrivs(playername) - & (PRIV_SERVER|PRIV_BAN|PRIV_PRIVS|PRIV_PASSWORD)) == 0 && + !checkPriv(playername, "server") && + !checkPriv(playername, "ban") && + !checkPriv(playername, "privs") && + !checkPriv(playername, "password") && playername != g_settings->get("name")) { actionstream<<"Server: "<getName(), "interact")) return; /* u16 command @@ -2519,9 +2516,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) // Disallow moving items in elsewhere than player's inventory // if not allowed to interact - if((getPlayerPrivs(player) & PRIV_INTERACT) == 0 - && (!from_inv_is_current_player - || !to_inv_is_current_player)) + if(!checkPriv(player->getName(), "interact") && + (!from_inv_is_current_player || + !to_inv_is_current_player)) { infostream<<"Cannot move outside of player's inventory: " <<"No interact privilege"<getName(), "server")) { std::string owner_from = getInventoryOwner(ma->from_inv); if(owner_from != "" && owner_from != player->getName()) @@ -2565,13 +2562,13 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) setInventoryModified(da->from_inv); // Disallow dropping items if not allowed to interact - if((getPlayerPrivs(player) & PRIV_INTERACT) == 0) + if(!checkPriv(player->getName(), "interact")) { delete a; return; } // If player is not an admin, check for ownership - else if((getPlayerPrivs(player) & PRIV_SERVER) == 0) + else if(!checkPriv(player->getName(), "server")) { std::string owner_from = getInventoryOwner(da->from_inv); if(owner_from != "" && owner_from != player->getName()) @@ -2600,7 +2597,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) // (ca->craft_inv.name == player->getName()); // Disallow crafting if not allowed to interact - if((getPlayerPrivs(player) & PRIV_INTERACT) == 0) + if(!checkPriv(player->getName(), "interact")) { infostream<<"Cannot craft: " <<"No interact privilege"<getName(), "server")) { std::string owner_craft = getInventoryOwner(ca->craft_inv); if(owner_craft != "" && owner_craft != player->getName()) @@ -2667,10 +2664,6 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) // Whether to send to other players bool send_to_others = false; - // Local player gets all privileges regardless of - // what's set on their account. - u64 privs = getPlayerPrivs(player); - // Parse commands if(message[0] == L'/') { @@ -2688,8 +2681,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) paramstring, this, m_env, - player, - privs); + player); std::wstring reply(processServerCommand(ctx)); send_to_sender = ctx->flags & SEND_TO_SENDER; @@ -2705,16 +2697,13 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) } else { - if(privs & PRIV_SHOUT) - { + if(checkPriv(player->getName(), "shout")){ line += L"<"; line += name; line += L"> "; line += message; send_to_others = true; - } - else - { + } else { line += L"Server: You are not allowed to shout"; send_to_sender = true; } @@ -2803,15 +2792,8 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) std::string playername = player->getName(); - if(m_authmanager.exists(playername) == false) - { - infostream<<"Server: playername not found in authmanager"<getName()<<" changes password"<getName()<<" changes password"<getName()<<" tries to change password but " + <<"it fails"<getName(), "interact")) { infostream<<"Ignoring interaction from player "<getName() - <<" because privileges are "< Server::getPlayerEffectivePrivs(const std::string &name) { - // Local player gets all privileges regardless of - // what's set on their account. - if(m_simple_singleplayer_mode) - return PRIV_ALL; - if(name == g_settings->get("name")) - return PRIV_ALL; - return getPlayerAuthPrivs(name); + std::set privs; + scriptapi_get_auth(m_lua, name, NULL, &privs); + return privs; } -void Server::setPlayerPassword(const std::string &name, const std::wstring &password) +bool Server::checkPriv(const std::string &name, const std::string &priv) { - // Add player to auth manager - if(m_authmanager.exists(name) == false) - { - infostream<<"Server: adding player "<get("default_privs"))); - } - // Change password and save - m_authmanager.setPassword(name, translatePassword(name, password)); - m_authmanager.save(); + std::set privs = getPlayerEffectivePrivs(name); + return (privs.count(priv) != 0); } // Saves g_settings to configpath given at initialization @@ -4698,14 +4644,6 @@ void Server::handlePeerChanges() } } -u64 Server::getPlayerPrivs(Player *player) -{ - if(player==NULL) - return 0; - std::string playername = player->getName(); - return getPlayerEffectivePrivs(playername); -} - void dedicated_server_loop(Server &server, bool &kill) { DSTACK(__FUNCTION_NAME); -- cgit v1.2.3