diff --git a/src/clientiface.cpp b/src/clientiface.cpp index 6563c404c..c2d245f67 100644 --- a/src/clientiface.cpp +++ b/src/clientiface.cpp @@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include "clientiface.h" +#include "debug.h" #include "network/connection.h" #include "network/serveropcodes.h" #include "remoteplayer.h" @@ -31,6 +32,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "server/player_sao.h" #include "log.h" #include "util/srp.h" +#include "util/string.h" #include "face_position_cache.h" static std::string string_sanitize_ascii(const std::string &s, u32 max_length) @@ -649,6 +651,14 @@ void RemoteClient::resetChosenMech() chosen_mech = AUTH_MECHANISM_NONE; } +void RemoteClient::setEncryptedPassword(const std::string& pwd) +{ + FATAL_ERROR_IF(!str_starts_with(pwd, "#1#"), "must be srp"); + enc_pwd = pwd; + // We just set SRP encrypted password, we accept only it now + allowed_auth_mechs = AUTH_MECHANISM_SRP; +} + void RemoteClient::setVersionInfo(u8 major, u8 minor, u8 patch, const std::string &full) { m_version_major = major; diff --git a/src/clientiface.h b/src/clientiface.h index 4d63ca815..138e7fc79 100644 --- a/src/clientiface.h +++ b/src/clientiface.h @@ -243,15 +243,14 @@ public: AuthMechanism chosen_mech = AUTH_MECHANISM_NONE; void *auth_data = nullptr; u32 allowed_auth_mechs = 0; - u32 allowed_sudo_mechs = 0; void resetChosenMech(); - bool isSudoMechAllowed(AuthMechanism mech) - { return allowed_sudo_mechs & mech; } bool isMechAllowed(AuthMechanism mech) { return allowed_auth_mechs & mech; } + void setEncryptedPassword(const std::string& pwd); + RemoteClient(); ~RemoteClient() = default; diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index 92ff4d031..934afb055 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -1515,8 +1515,7 @@ void Server::handleCommand_FirstSrp(NetworkPacket* pkt) return; } - std::string initial_ver_key; - initial_ver_key = encode_srp_verifier(verification_key, salt); + std::string encpwd = encode_srp_verifier(verification_key, salt); // It is possible for multiple connections to get this far with the same // player name. In the end only one player with a given name will be emerged @@ -1529,9 +1528,11 @@ void Server::handleCommand_FirstSrp(NetworkPacket* pkt) DenyAccess(peer_id, SERVER_ACCESSDENIED_ALREADY_CONNECTED); return; } - m_script->createAuth(playername, initial_ver_key); - m_script->on_authplayer(playername, addr_s, true); + m_script->createAuth(playername, encpwd); + client->setEncryptedPassword(encpwd); + + m_script->on_authplayer(playername, addr_s, true); acceptAuth(peer_id, false); } else { if (cstate < CS_SudoMode) { @@ -1550,12 +1551,13 @@ void Server::handleCommand_FirstSrp(NetworkPacket* pkt) return; } - std::string pw_db_field = encode_srp_verifier(verification_key, salt); - bool success = m_script->setPassword(playername, pw_db_field); + std::string encpwd = encode_srp_verifier(verification_key, salt); + bool success = m_script->setPassword(playername, encpwd); if (success) { actionstream << playername << " changes password" << std::endl; SendChatMessage(peer_id, ChatMessage(CHATMESSAGE_TYPE_SYSTEM, L"Password change successful.")); + client->setEncryptedPassword(encpwd); } else { actionstream << playername << " tries to change password but it fails" << std::endl; @@ -1606,7 +1608,8 @@ void Server::handleCommand_SrpBytesA(NetworkPacket* pkt) AUTH_MECHANISM_LEGACY_PASSWORD : AUTH_MECHANISM_SRP; if (wantSudo) { - if (!client->isSudoMechAllowed(chosen)) { + // Right now, the auth mechs don't change between login and sudo mode. + if (!client->isMechAllowed(chosen)) { actionstream << "Server: Player \"" << client->getName() << "\" at " << getPeerAddress(peer_id).serializeString() << " tried to change password using unallowed mech " << chosen << diff --git a/src/server.cpp b/src/server.cpp index da9c5c10d..4c0788e8d 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -2902,13 +2902,9 @@ void Server::acceptAuth(session_t peer_id, bool forSudoMode) NetworkPacket resp_pkt(TOCLIENT_AUTH_ACCEPT, 1 + 6 + 8 + 4, peer_id); - // Right now, the auth mechs don't change between login and sudo mode. - u32 sudo_auth_mechs = client->allowed_auth_mechs; - client->allowed_sudo_mechs = sudo_auth_mechs; - resp_pkt << v3f(0,0,0) << (u64) m_env->getServerMap().getSeed() << g_settings->getFloat("dedicated_server_step") - << sudo_auth_mechs; + << client->allowed_auth_mechs; Send(&resp_pkt); m_clients.event(peer_id, CSE_AuthAccept);