Network: Fix logging into older worlds with base64 hashes

This commit is contained in:
SmallJoker 2017-09-12 20:26:03 +02:00
parent ee9a442ecc
commit 5e141ac920
4 changed files with 28 additions and 11 deletions

@ -920,10 +920,10 @@ void Client::deleteAuthData()
case AUTH_MECHANISM_FIRST_SRP: case AUTH_MECHANISM_FIRST_SRP:
break; break;
case AUTH_MECHANISM_SRP: case AUTH_MECHANISM_SRP:
case AUTH_MECHANISM_LEGACY_PASSWORD:
srp_user_delete((SRPUser *) m_auth_data); srp_user_delete((SRPUser *) m_auth_data);
m_auth_data = NULL; m_auth_data = NULL;
break; break;
case AUTH_MECHANISM_LEGACY_PASSWORD:
case AUTH_MECHANISM_NONE: case AUTH_MECHANISM_NONE:
break; break;
} }
@ -939,6 +939,9 @@ AuthMechanism Client::choseAuthMech(const u32 mechs)
if (mechs & AUTH_MECHANISM_FIRST_SRP) if (mechs & AUTH_MECHANISM_FIRST_SRP)
return AUTH_MECHANISM_FIRST_SRP; return AUTH_MECHANISM_FIRST_SRP;
if (mechs & AUTH_MECHANISM_LEGACY_PASSWORD)
return AUTH_MECHANISM_LEGACY_PASSWORD;
return AUTH_MECHANISM_NONE; return AUTH_MECHANISM_NONE;
} }
@ -974,8 +977,14 @@ void Client::startAuth(AuthMechanism chosen_auth_mechanism)
Send(&resp_pkt); Send(&resp_pkt);
break; break;
} }
case AUTH_MECHANISM_SRP: { case AUTH_MECHANISM_SRP:
u8 legacy_based_on = 1; case AUTH_MECHANISM_LEGACY_PASSWORD: {
u8 based_on = 1;
if (chosen_auth_mechanism == AUTH_MECHANISM_LEGACY_PASSWORD) {
m_password = translate_password(getPlayerName(), m_password);
based_on = 0;
}
std::string playername_u = lowercase(getPlayerName()); std::string playername_u = lowercase(getPlayerName());
m_auth_data = srp_user_new(SRP_SHA256, SRP_NG_2048, m_auth_data = srp_user_new(SRP_SHA256, SRP_NG_2048,
@ -990,11 +999,10 @@ void Client::startAuth(AuthMechanism chosen_auth_mechanism)
FATAL_ERROR_IF(res != SRP_OK, "Creating local SRP user failed."); FATAL_ERROR_IF(res != SRP_OK, "Creating local SRP user failed.");
NetworkPacket resp_pkt(TOSERVER_SRP_BYTES_A, 0); NetworkPacket resp_pkt(TOSERVER_SRP_BYTES_A, 0);
resp_pkt << std::string(bytes_A, len_A) << legacy_based_on; resp_pkt << std::string(bytes_A, len_A) << based_on;
Send(&resp_pkt); Send(&resp_pkt);
break; break;
} }
case AUTH_MECHANISM_LEGACY_PASSWORD:
case AUTH_MECHANISM_NONE: case AUTH_MECHANISM_NONE:
break; // not handled in this method break; // not handled in this method
} }

@ -454,7 +454,8 @@ void RemoteClient::notifyEvent(ClientStateEvent event)
{ {
case CSE_AuthAccept: case CSE_AuthAccept:
m_state = CS_AwaitingInit2; m_state = CS_AwaitingInit2;
if (chosen_mech == AUTH_MECHANISM_SRP) if (chosen_mech == AUTH_MECHANISM_SRP ||
chosen_mech == AUTH_MECHANISM_LEGACY_PASSWORD)
srp_verifier_delete((SRPVerifier *) auth_data); srp_verifier_delete((SRPVerifier *) auth_data);
chosen_mech = AUTH_MECHANISM_NONE; chosen_mech = AUTH_MECHANISM_NONE;
break; break;
@ -463,7 +464,8 @@ void RemoteClient::notifyEvent(ClientStateEvent event)
break; break;
case CSE_SetDenied: case CSE_SetDenied:
m_state = CS_Denied; m_state = CS_Denied;
if (chosen_mech == AUTH_MECHANISM_SRP) if (chosen_mech == AUTH_MECHANISM_SRP ||
chosen_mech == AUTH_MECHANISM_LEGACY_PASSWORD)
srp_verifier_delete((SRPVerifier *) auth_data); srp_verifier_delete((SRPVerifier *) auth_data);
chosen_mech = AUTH_MECHANISM_NONE; chosen_mech = AUTH_MECHANISM_NONE;
break; break;

@ -86,7 +86,8 @@ void Client::handleCommand_Hello(NetworkPacket* pkt)
// we recieved a TOCLIENT_HELLO while auth was already going on // we recieved a TOCLIENT_HELLO while auth was already going on
errorstream << "Client: 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; << "(chosen_mech=" << m_chosen_auth_mech << ")." << std::endl;
if (m_chosen_auth_mech == AUTH_MECHANISM_SRP) { if (m_chosen_auth_mech == AUTH_MECHANISM_SRP ||
m_chosen_auth_mech == AUTH_MECHANISM_LEGACY_PASSWORD) {
srp_user_delete((SRPUser *) m_auth_data); srp_user_delete((SRPUser *) m_auth_data);
m_auth_data = 0; m_auth_data = 0;
} }
@ -1294,7 +1295,8 @@ void Client::handleCommand_UpdatePlayerList(NetworkPacket* pkt)
void Client::handleCommand_SrpBytesSandB(NetworkPacket* pkt) void Client::handleCommand_SrpBytesSandB(NetworkPacket* pkt)
{ {
if (m_chosen_auth_mech != AUTH_MECHANISM_SRP) { if (m_chosen_auth_mech != AUTH_MECHANISM_SRP &&
m_chosen_auth_mech != AUTH_MECHANISM_LEGACY_PASSWORD) {
errorstream << "Client: Received SRP S_B login message," errorstream << "Client: Received SRP S_B login message,"
<< " but wasn't supposed to (chosen_mech=" << " but wasn't supposed to (chosen_mech="
<< m_chosen_auth_mech << ")." << std::endl; << m_chosen_auth_mech << ")." << std::endl;

@ -232,6 +232,9 @@ void Server::handleCommand_Init(NetworkPacket* pkt)
DenyAccess(pkt->getPeerId(), SERVER_ACCESSDENIED_SERVER_FAIL); DenyAccess(pkt->getPeerId(), SERVER_ACCESSDENIED_SERVER_FAIL);
return; return;
} }
} else if (base64_is_valid(encpwd)) {
auth_mechs |= AUTH_MECHANISM_LEGACY_PASSWORD;
client->enc_pwd = encpwd;
} else { } else {
actionstream << "User " << playername actionstream << "User " << playername
<< " tried to log in, but password field" << " tried to log in, but password field"
@ -1578,7 +1581,8 @@ void Server::handleCommand_SrpBytesA(NetworkPacket* pkt)
<< "based_on=" << int(based_on) << " and len_A=" << "based_on=" << int(based_on) << " and len_A="
<< bytes_A.length() << "." << std::endl; << bytes_A.length() << "." << std::endl;
AuthMechanism chosen = AUTH_MECHANISM_SRP; AuthMechanism chosen = (based_on == 0) ?
AUTH_MECHANISM_LEGACY_PASSWORD : AUTH_MECHANISM_SRP;
if (wantSudo) { if (wantSudo) {
if (!client->isSudoMechAllowed(chosen)) { if (!client->isSudoMechAllowed(chosen)) {
@ -1663,7 +1667,8 @@ void Server::handleCommand_SrpBytesM(NetworkPacket* pkt)
return; return;
} }
if (client->chosen_mech != AUTH_MECHANISM_SRP) { if (client->chosen_mech != AUTH_MECHANISM_SRP &&
client->chosen_mech != AUTH_MECHANISM_LEGACY_PASSWORD) {
actionstream << "Server: got SRP _M packet, while auth" actionstream << "Server: got SRP _M packet, while auth"
<< "is going on with mech " << client->chosen_mech << "is going on with mech " << client->chosen_mech
<< " from " << getPeerAddress(pkt->getPeerId()).serializeString() << " from " << getPeerAddress(pkt->getPeerId()).serializeString()