1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

Make early protocol auth mechanism generic, and add SRP

Adds everything needed for SRP (and everything works too),
but still deactivated, as protocol v25 init packets aren't final yet.
Can be activated by changing the LATEST_PROTOCOL_VERSION header to 25
inside networkprotocol.h.
This commit is contained in:
est31 2015-04-12 04:49:13 +02:00
parent 181f7baa45
commit 82e35edff5
25 changed files with 3351 additions and 309 deletions

View file

@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "strfnd.h"
#include "network/clientopcodes.h"
#include "util/serialize.h"
#include "util/srp.h"
void Client::handleCommand_Deprecated(NetworkPacket* pkt)
{
@ -44,10 +45,16 @@ void Client::handleCommand_Hello(NetworkPacket* pkt)
return;
u8 deployed;
*pkt >> deployed;
u32 auth_mechs;
std::string username_legacy; // for case insensitivity
*pkt >> deployed >> auth_mechs >> username_legacy;
// Chose an auth method we support
AuthMechanism chosen_auth_mechanism = choseAuthMech(auth_mechs);
infostream << "Client: TOCLIENT_HELLO received with "
"deployed=" << ((int)deployed & 0xff) << std::endl;
"deployed=" << ((int)deployed & 0xff) << ", auth_mechs="
<< auth_mechs << ", chosen=" << chosen_auth_mechanism << std::endl;
if (!ser_ver_supported(deployed)) {
infostream << "Client: TOCLIENT_HELLO: Server sent "
@ -56,14 +63,43 @@ void Client::handleCommand_Hello(NetworkPacket* pkt)
}
m_server_ser_ver = deployed;
m_proto_ver = deployed;
//TODO verify that username_legacy matches sent username, only
// differs in casing (make both uppercase and compare)
// This is only neccessary though when we actually want to add casing support
if (m_chosen_auth_mech != AUTH_MECHANISM_NONE) {
// we recieved a TOCLIENT_HELLO while auth was already going on
errorstream << "Client: TOCLIENT_HELLO while auth was already going on"
<< "(chosen_mech=" << m_chosen_auth_mech << ")." << std::endl;
if ((m_chosen_auth_mech == AUTH_MECHANISM_SRP)
|| (m_chosen_auth_mech == AUTH_MECHANISM_LEGACY_PASSWORD)) {
srp_user_delete((SRPUser *) m_auth_data);
m_auth_data = 0;
}
}
// Authenticate using that method, or abort if there wasn't any method found
if (chosen_auth_mechanism != AUTH_MECHANISM_NONE) {
startAuth(chosen_auth_mechanism);
} else {
m_chosen_auth_mech = AUTH_MECHANISM_NONE;
m_access_denied = true;
m_access_denied_reason = "Unknown";
m_con.Disconnect();
}
// @ TODO auth to server
}
void Client::handleCommand_AuthAccept(NetworkPacket* pkt)
{
m_chosen_auth_mech = AUTH_MECHANISM_NONE;
deleteAuthData();
v3f playerpos;
*pkt >> playerpos >> m_map_seed >> m_recommended_send_interval;
*pkt >> playerpos >> m_map_seed >> m_recommended_send_interval
>> m_sudo_auth_methods;
playerpos -= v3f(0, BS / 2, 0);
@ -82,7 +118,28 @@ void Client::handleCommand_AuthAccept(NetworkPacket* pkt)
m_state = LC_Init;
}
void Client::handleCommand_AcceptSudoMode(NetworkPacket* pkt)
{
m_chosen_auth_mech = AUTH_MECHANISM_NONE;
deleteAuthData();
m_password = m_new_password;
verbosestream << "Client: Recieved TOCLIENT_ACCEPT_SUDO_MODE." << std::endl;
// send packet to actually set the password
startAuth(AUTH_MECHANISM_FIRST_SRP);
// reset again
m_chosen_auth_mech = AUTH_MECHANISM_NONE;
}
void Client::handleCommand_DenySudoMode(NetworkPacket* pkt)
{
m_chat_queue.push(L"Password change denied. Password NOT changed.");
// reset everything and be sad
deleteAuthData();
m_chosen_auth_mech = AUTH_MECHANISM_NONE;
}
void Client::handleCommand_InitLegacy(NetworkPacket* pkt)
{
if (pkt->getSize() < 1)
@ -101,6 +158,7 @@ void Client::handleCommand_InitLegacy(NetworkPacket* pkt)
}
m_server_ser_ver = deployed;
m_proto_ver = deployed;
// Get player position
v3s16 playerpos_s16(0, BS * 2 + BS * 20, 0);
@ -1105,3 +1163,36 @@ void Client::handleCommand_EyeOffset(NetworkPacket* pkt)
*pkt >> player->eye_offset_first >> player->eye_offset_third;
}
void Client::handleCommand_SrpBytesSandB(NetworkPacket* pkt)
{
if ((m_chosen_auth_mech != AUTH_MECHANISM_LEGACY_PASSWORD)
&& (m_chosen_auth_mech != AUTH_MECHANISM_SRP)) {
errorstream << "Client: Recieved SRP S_B login message,"
<< " but wasn't supposed to (chosen_mech="
<< m_chosen_auth_mech << ")." << std::endl;
return;
}
char *bytes_M = 0;
size_t len_M = 0;
SRPUser *usr = (SRPUser *) m_auth_data;
std::string s;
std::string B;
*pkt >> s >> B;
infostream << "Client: Recieved TOCLIENT_SRP_BYTES_S_B." << std::endl;
srp_user_process_challenge(usr, (const unsigned char *) s.c_str(), s.size(),
(const unsigned char *) B.c_str(), B.size(),
(unsigned char **) &bytes_M, &len_M);
if ( !bytes_M ) {
errorstream << "Client: SRP-6a S_B safety check violation!" << std::endl;
return;
}
NetworkPacket resp_pkt(TOSERVER_SRP_BYTES_M, 0);
resp_pkt << std::string(bytes_M, len_M);
Send(&resp_pkt);
}