Index: Main.cpp =================================================================== --- Main.cpp (révision 5109) +++ Main.cpp (copie de travail) @@ -31,6 +31,8 @@ #include "SystemConfig.h" #include "Util.h" +#include "AccountHandler.h" + #ifdef WIN32 #include "ServiceWin32.h" char serviceName[] = "realmd"; @@ -185,6 +187,14 @@ ///- Launch the listening network socket port_t rmport = sConfig.GetIntDefault( "RealmServerPort", DEFAULT_REALMSERVER_PORT ); + // Activate or not account caching system, precache them before launching connection port + if(sConfig.GetIntDefault("AccountCaching", 0) == 1) + { + AcctMgr.Initialize(sConfig.GetIntDefault("AccountReloadingDelay", 300)); + sLog.outString(); + sLog.outString("Accounts will be reloaded in %u seconds", sConfig.GetIntDefault("AccountReloadingDelay", 300)); + } + SocketHandler h; ListenSocket authListenSocket(h); if ( authListenSocket.Bind(rmport)) Index: Makefile.am =================================================================== --- Makefile.am (révision 5109) +++ Makefile.am (copie de travail) @@ -27,7 +27,9 @@ AuthSocket.h \ Main.cpp \ RealmList.cpp \ - RealmList.h + RealmList.h \ + AccountHandler.cpp \ + AccountHandler.h ## Link realm list daemon against the shared library mangos_realmd_LDADD = ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../framework/libmangosframework.a ../../dep/src/sockets/libmangossockets.a ../../dep/src/zthread/libZThread.la Index: AuthSocket.cpp =================================================================== --- AuthSocket.cpp (révision 5109) +++ AuthSocket.cpp (copie de travail) @@ -30,6 +30,9 @@ #include // needs for towupper #include #include "Auth/Sha1.h" +#include "AccountHandler.h" +#include "Config/ConfigEnv.h" +#include extern RealmList m_realmList; @@ -320,6 +323,8 @@ /// Logon Challenge command handler bool AuthSocket::_HandleLogonChallenge() { + AcctMgr.ReloadEverythingIfNeed(); + DEBUG_LOG("Entering _HandleLogonChallenge"); if (ibuf.GetLength() < sizeof(sAuthLogonChallenge_C)) return false; @@ -370,6 +375,8 @@ pkt << (uint8) AUTH_LOGON_CHALLENGE; pkt << (uint8) 0x00; + if(sConfig.GetIntDefault("AccountCaching", 0) != 1) + { ///- Verify that this IP is not in the ip_banned table // No SQL injection possible (paste the IP address as passed by the socket) dbRealmServer.Execute("DELETE FROM `ip_banned` WHERE `unbandate`<=UNIX_TIMESTAMP() AND `unbandate`<>`bandate`"); @@ -484,10 +491,98 @@ { pkt<< (uint8) REALM_AUTH_NO_MATCH; } - } - } //valid version + } + } + else + { + if(AcctMgr.IpBan(GetRemoteAddress())) + { + pkt << (uint8)REALM_AUTH_ACCOUNT_BANNED; + } + else + { + Account* acct = AcctMgr.FindAccountByName(_safelogin); + + if(acct) + { + bool locked = false; + + if(acct->locked == 1) // if ip is locked + { + if ( strcmp(acct->LastIp.c_str(),GetRemoteAddress().c_str()) ) + { + pkt << (uint8) REALM_AUTH_ACCOUNT_FREEZED; + locked=true; + } + } + + if (!locked) + { + if(acct->banned) + { + pkt << (uint8) REALM_AUTH_ACCOUNT_BANNED; + } + else + { + ///- Get the password from the account table, upper it, and make the SRP6 calculation + std::string rI = acct->I; + _SetVSFields(rI); + b.SetRand(19 * 8); + BigNumber gmod=g.ModExp(b, N); + B = ((v * 3) + gmod) % N; + + if (B.GetNumBytes() < 32) + sLog.outDetail("Interesting, calculation of B in realmd is < 32."); + + ASSERT(gmod.GetNumBytes() <= 32); + + BigNumber unk3; + unk3.SetRand(16*8); + + ///- Fill the response packet with the result + pkt << (uint8)REALM_AUTH_SUCCESS; + pkt.append(B.AsByteArray(), B.GetNumBytes()); + pkt << (uint8)1; + pkt.append(g.AsByteArray(), 1); + pkt << (uint8)32; + pkt.append(N.AsByteArray(), 32); + pkt.append(s.AsByteArray(), s.GetNumBytes()); + pkt.append(unk3.AsByteArray(), 16); + pkt << (uint8)0; // Added in 1.12.x client branch + + uint8 secLevel = acct->security; + _accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR; + + // There isn't many differents locale so i think we can hardcode them all + + char charbuffer[3]; + charbuffer[0] = ch->country[3]; + charbuffer[1] = ch->country[2]; + charbuffer[2] = '\0'; + + if(strcmp (charbuffer,"fr") == 0) + _localization = 2; + else if(strcmp (charbuffer,"de") == 0) + _localization = 3; + else + _localization = 0; + + } + } + else + { + pkt << (uint8) REALM_AUTH_ACCOUNT_FREEZED; + } + } + else //no account + { + pkt<< (uint8) REALM_AUTH_NO_MATCH; + } + } + } + } //valid version else - ///
  • else + ///
  • else { ///- Check if we have the apropriate patch on the disk char tmp[64]; @@ -535,7 +630,7 @@ } /// SendBuf((char const*)pkt.contents(), pkt.size()); - return true; + return true; } /// Logon Proof command handler @@ -664,6 +759,11 @@ ///- Get the user id (else close the connection) // No SQL injection (escaped user name) + std::string rI; + uint32 id; + + if(sConfig.GetIntDefault("AccountCaching", 0) != 1) + { QueryResult *result = dbRealmServer.PQuery("SELECT `id`,`I` FROM `account` WHERE `username` = '%s'",_safelogin.c_str()); if(!result) { @@ -672,9 +772,16 @@ return false; } - uint32 id = (*result)[0].GetUInt32(); - std::string rI = (*result)[1].GetCppString(); + id = (*result)[0].GetUInt32(); + rI = (*result)[1].GetCppString(); delete result; + } + else + { + Account* acct = AcctMgr.FindAccountByName(_safelogin); + id = acct->id; + rI = acct->I; + } ///- Update realm list if need m_realmList.UpdateIfNeed(); @@ -688,16 +795,31 @@ { uint8 AmountOfCharacters; - // No SQL injection. id of realm is controlled by the database. - result = dbRealmServer.PQuery( "SELECT `numchars` FROM `realmcharacters` WHERE `realmid` = '%d' AND `acctid`='%u'",i->second.m_ID,id); - if( result ) - { - Field *fields = result->Fetch(); - AmountOfCharacters = fields[0].GetUInt8(); - delete result; - } - else - AmountOfCharacters = 0; + /*if(sConfig.GetIntDefault("AccountCaching", 0) != 1) + { + // No SQL injection. id of realm is controlled by the database.*/ + QueryResult* result = dbRealmServer.PQuery( "SELECT `numchars` FROM `realmcharacters` WHERE `realmid` = '%d' AND `acctid`='%u'",i->second.m_ID,id); + if( result ) + { + Field *fields = result->Fetch(); + AmountOfCharacters = fields[0].GetUInt8(); + delete result; + } + else + AmountOfCharacters = 0; + /*} + else + { + AmountOfCharacters = AcctMgr.GetNumChar(i->second.m_ID, id); + // Why client stay at connected at disconnect / reconnect if we don't wait 100 ms before sending realmlist ... Don't understand why this isn't needed at first connection... We doesn't have this problem before since + // Query take time so i think this was the thing who make this problem not appear ... + #ifdef WIN32 + sleep(100); + #else + ZThread::Thread::sleep(100); + #endif + }*/ + uint8 lock = (i->second.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0;