summaryrefslogtreecommitdiff
path: root/src/server.cpp
diff options
context:
space:
mode:
authorPerttu Ahola <celeron55@gmail.com>2012-03-30 18:42:18 +0300
committerPerttu Ahola <celeron55@gmail.com>2012-03-30 18:42:18 +0300
commit7cad0a2dcd817b179f82066964c45937a603d138 (patch)
treef97c0ea3d9ccc5b67688fa1110b972c610a65430 /src/server.cpp
parented1ff06867e84f197330b45168c6ebcba672e532 (diff)
downloadminetest-7cad0a2dcd817b179f82066964c45937a603d138.tar.gz
minetest-7cad0a2dcd817b179f82066964c45937a603d138.tar.bz2
minetest-7cad0a2dcd817b179f82066964c45937a603d138.zip
Reimplement authentication handler in Lua; now we have 1) infinite privilege names, 2) minetest.register_authentication_handler()
Diffstat (limited to 'src/server.cpp')
-rw-r--r--src/server.cpp178
1 files changed, 58 insertions, 120 deletions
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 "<<playername
- <<" to auth manager"<<std::endl;
- m_authmanager.add(playername);
- m_authmanager.setPassword(playername, translated_default_password);
- m_authmanager.setPrivs(playername,
- stringToPrivs(g_settings->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 '"<<password
- <<"', the correct one is '"<<checkpwd<<"'"<<std::endl;*/
+ if(!has_auth){
+ SendAccessDenied(m_con, peer_id, L"Not allowed to login");
+ return;
+ }
- if(password != checkpwd)
- {
+ if(password != checkpwd){
infostream<<"Server: peer_id="<<peer_id
<<": supplied invalid password for "
<<playername<<std::endl;
@@ -2131,8 +2126,10 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
// Enforce user limit.
// Don't enforce for users that have some admin right
if(m_clients.size() >= 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: "<<playername<<" tried to join, but there"
@@ -2407,7 +2404,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
}
else if(command == TOSERVER_SIGNNODETEXT)
{
- if((getPlayerPrivs(player) & PRIV_INTERACT) == 0)
+ if(!checkPriv(player->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"<<std::endl;
@@ -2530,7 +2527,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
}
// If player is not an admin, check for ownership of src and dst
- if((getPlayerPrivs(player) & PRIV_SERVER) == 0)
+ if(!checkPriv(player->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"<<std::endl;
@@ -2609,7 +2606,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
}
// If player is not an admin, check for ownership of inventory
- if((getPlayerPrivs(player) & PRIV_SERVER) == 0)
+ if(!checkPriv(player->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"<<std::endl;
- // Wrong old password supplied!!
- SendChatMessage(peer_id, L"playername not found in authmanager");
- return;
- }
-
- std::string checkpwd = m_authmanager.getPassword(playername);
+ std::string checkpwd;
+ scriptapi_get_auth(m_lua, playername, &checkpwd, NULL);
if(oldpwd != checkpwd)
{
@@ -2821,13 +2803,15 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
return;
}
- actionstream<<player->getName()<<" changes password"<<std::endl;
-
- m_authmanager.setPassword(playername, newpwd);
-
- infostream<<"Server: password change successful for "<<playername
- <<std::endl;
- SendChatMessage(peer_id, L"Password change successful");
+ bool success = scriptapi_set_password(m_lua, playername, newpwd);
+ if(success){
+ actionstream<<player->getName()<<" changes password"<<std::endl;
+ SendChatMessage(peer_id, L"Password change successful");
+ } else {
+ actionstream<<player->getName()<<" tries to change password but "
+ <<"it fails"<<std::endl;
+ SendChatMessage(peer_id, L"Password change failed or inavailable");
+ }
}
else if(command == TOSERVER_PLAYERITEM)
{
@@ -2970,11 +2954,10 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
/*
Make sure the player is allowed to do it
*/
- if((getPlayerPrivs(player) & PRIV_INTERACT) == 0)
+ if(!checkPriv(player->getName(), "interact"))
{
infostream<<"Ignoring interaction from player "<<player->getName()
- <<" because privileges are "<<getPlayerPrivs(player)
- <<std::endl;
+ <<" (no interact privilege)"<<std::endl;
return;
}
@@ -4277,54 +4260,17 @@ std::wstring Server::getStatusString()
return os.str();
}
-u64 Server::getPlayerAuthPrivs(const std::string &name)
-{
- try{
- return m_authmanager.getPrivs(name);
- }
- catch(AuthNotFoundException &e)
- {
- dstream<<"WARNING: Auth not found for "<<name<<std::endl;
- return 0;
- }
-}
-
-void Server::setPlayerAuthPrivs(const std::string &name, u64 privs)
-{
- try{
- return m_authmanager.setPrivs(name, privs);
- }
- catch(AuthNotFoundException &e)
- {
- dstream<<"WARNING: Auth not found for "<<name<<std::endl;
- }
-}
-
-u64 Server::getPlayerEffectivePrivs(const std::string &name)
+std::set<std::string> 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<std::string> 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 "<<name
- <<" to auth manager"<<std::endl;
- m_authmanager.add(name);
- m_authmanager.setPrivs(name,
- stringToPrivs(g_settings->get("default_privs")));
- }
- // Change password and save
- m_authmanager.setPassword(name, translatePassword(name, password));
- m_authmanager.save();
+ std::set<std::string> 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);