mirror of
https://github.com/mangosfour/server.git
synced 2025-12-16 13:37:00 +00:00
[8445] Fixed redundant calculation of v and s on every login
The SRP-6 specifications clearly say, that v and s are only to be calculated on registering a user and changing his password; calculating them on every login is plain waste.
This commit is contained in:
parent
4d0088e7a9
commit
3b1b68595b
8 changed files with 47 additions and 60 deletions
|
|
@ -246,7 +246,6 @@ void AuthSocket::OnAccept()
|
|||
sLog.outBasic("Accepting connection from '%s:%d'",
|
||||
GetRemoteAddress().c_str(), GetRemotePort());
|
||||
|
||||
s.SetRand(s_BYTE_SIZE * 8);
|
||||
}
|
||||
|
||||
/// Read the packet from the client
|
||||
|
|
@ -295,6 +294,8 @@ void AuthSocket::OnRead()
|
|||
/// Make the SRP6 calculation from hash in dB
|
||||
void AuthSocket::_SetVSFields(const std::string& rI)
|
||||
{
|
||||
s.SetRand(s_BYTE_SIZE * 8);
|
||||
|
||||
BigNumber I;
|
||||
I.SetHexStr(rI.c_str());
|
||||
|
||||
|
|
@ -396,7 +397,7 @@ bool AuthSocket::_HandleLogonChallenge()
|
|||
///- Get the account details from the account table
|
||||
// No SQL injection (escaped user name)
|
||||
|
||||
result = loginDatabase.PQuery("SELECT sha_pass_hash,id,locked,last_ip,gmlevel FROM account WHERE username = '%s'",_safelogin.c_str ());
|
||||
result = loginDatabase.PQuery("SELECT sha_pass_hash,id,locked,last_ip,gmlevel,v,s FROM account WHERE username = '%s'",_safelogin.c_str ());
|
||||
if( result )
|
||||
{
|
||||
///- If the IP is 'locked', check that the player comes indeed from the correct IP address
|
||||
|
|
@ -446,7 +447,21 @@ bool AuthSocket::_HandleLogonChallenge()
|
|||
{
|
||||
///- Get the password from the account table, upper it, and make the SRP6 calculation
|
||||
std::string rI = (*result)[0].GetCppString();
|
||||
_SetVSFields(rI);
|
||||
|
||||
///- Don't calculate (v, s) if there are already some in the database
|
||||
std::string databaseV = (*result)[5].GetCppString();
|
||||
std::string databaseS = (*result)[6].GetCppString();
|
||||
|
||||
sLog.outDebug("database authentication values: v='%s' s='%s'", databaseV.c_str(), databaseS.c_str());
|
||||
|
||||
// multiply with 2, bytes are stored as hexstring
|
||||
if(databaseV.size() != s_BYTE_SIZE*2 || databaseS.size() != s_BYTE_SIZE*2)
|
||||
_SetVSFields(rI);
|
||||
else
|
||||
{
|
||||
s.SetHexStr(databaseS.c_str());
|
||||
v.SetHexStr(databaseV.c_str());
|
||||
}
|
||||
|
||||
b.SetRand(19 * 8);
|
||||
BigNumber gmod = g.ModExp(b, N);
|
||||
|
|
@ -591,8 +606,13 @@ bool AuthSocket::_HandleLogonProof()
|
|||
|
||||
///- Continue the SRP6 calculation based on data received from the client
|
||||
BigNumber A;
|
||||
|
||||
A.SetBinary(lp.A, 32);
|
||||
|
||||
// SRP safeguard: abort if A==0
|
||||
if (A.isZero())
|
||||
return false;
|
||||
|
||||
Sha1Hash sha;
|
||||
sha.UpdateBigNumbers(&A, &B, NULL);
|
||||
sha.Finalize();
|
||||
|
|
@ -603,7 +623,7 @@ bool AuthSocket::_HandleLogonProof()
|
|||
uint8 t[32];
|
||||
uint8 t1[16];
|
||||
uint8 vK[40];
|
||||
memcpy(t, S.AsByteArray(), 32);
|
||||
memcpy(t, S.AsByteArray(32), 32);
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
t1[i] = t[i * 2];
|
||||
|
|
@ -905,8 +925,6 @@ bool AuthSocket::_HandleRealmList()
|
|||
|
||||
SendBuf((char const*)hdr.contents(), hdr.size());
|
||||
|
||||
// Set check field before possible relogin to realm
|
||||
_SetVSFields(rI);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue