diff options
author | megamage <none@none> | 2009-09-02 16:22:32 -0500 |
---|---|---|
committer | megamage <none@none> | 2009-09-02 16:22:32 -0500 |
commit | 790c5348a33ad28422e9356e598bf7084b0159b6 (patch) | |
tree | 78b79b129c84c9f184f00ce9c152965bc43a65a8 /src/trinityrealm/AuthSocket.cpp | |
parent | 0c0a7b6b0ee55aa1c58a82b2afdc48614f3342bc (diff) |
[8445] Fixed redundant calculation of v and s on every login Author: arrai
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.
--HG--
branch : trunk
Diffstat (limited to 'src/trinityrealm/AuthSocket.cpp')
-rw-r--r-- | src/trinityrealm/AuthSocket.cpp | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/src/trinityrealm/AuthSocket.cpp b/src/trinityrealm/AuthSocket.cpp index 14dadb1f2e2..88cd3aa0ec9 100644 --- a/src/trinityrealm/AuthSocket.cpp +++ b/src/trinityrealm/AuthSocket.cpp @@ -248,7 +248,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 @@ -297,6 +296,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()); @@ -398,7 +399,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 @@ -448,7 +449,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); @@ -593,8 +608,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(); @@ -605,7 +625,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]; @@ -906,8 +926,6 @@ bool AuthSocket::_HandleRealmList() SendBuf((char const*)hdr.contents(), hdr.size()); - // Set check field before possible relogin to realm - _SetVSFields(rI); return true; } |