[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:
arrai 2009-09-01 02:31:36 +02:00
parent 4d0088e7a9
commit 3b1b68595b
8 changed files with 47 additions and 60 deletions

View file

@ -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;
}