Core/Authserver: Cleanup.

--HG--
branch : trunk
This commit is contained in:
silinoron
2010-12-04 11:19:41 -08:00
parent 3201338eac
commit b8bf37264b
4 changed files with 64 additions and 77 deletions
@@ -6,26 +6,22 @@ namespace AuthHelper
bool IsPreBCAcceptedClientBuild(int build) bool IsPreBCAcceptedClientBuild(int build)
{ {
int accepted_versions[] = PRE_BC_ACCEPTED_CLIENT_BUILD; int accepted_versions[] = PRE_BC_ACCEPTED_CLIENT_BUILD;
for (int i = 0; accepted_versions[i]; ++i) for (int i = 0; accepted_versions[i]; ++i)
{
if (build == accepted_versions[i]) if (build == accepted_versions[i])
{
return true; return true;
}
}
return false; return false;
} }
bool IsPostBCAcceptedClientBuild(int build) bool IsPostBCAcceptedClientBuild(int build)
{ {
int accepted_versions[] = POST_BC_ACCEPTED_CLIENT_BUILD; int accepted_versions[] = POST_BC_ACCEPTED_CLIENT_BUILD;
for (int i = 0; accepted_versions[i]; ++i) for (int i = 0; accepted_versions[i]; ++i)
{
if (build == accepted_versions[i]) if (build == accepted_versions[i])
{
return true; return true;
}
}
return false; return false;
} }
@@ -74,9 +74,11 @@ enum LoginResult
//3.1.3 build 9947 //3.1.3 build 9947
//3.1.3 build 10146 Chinese build //3.1.3 build 10146 Chinese build
//3.2.2a build 10505 //3.2.2a build 10505
//3.3.0 build 10571
//3.3.0a build 11159 //3.3.0a build 11159
//3.3.2 build 11403 //3.3.2 build 11403
//3.3.3a build 11723 //3.3.3a build 11723
//3.3.5a build 12340
#define POST_BC_ACCEPTED_CLIENT_BUILD {12340, 11723, 11403, 11159, 10571, 10505, 10146, 9947, 8606, 0} #define POST_BC_ACCEPTED_CLIENT_BUILD {12340, 11723, 11403, 11159, 10571, 10505, 10146, 9947, 8606, 0}
#define PRE_BC_ACCEPTED_CLIENT_BUILD {5875, 6005, 0} #define PRE_BC_ACCEPTED_CLIENT_BUILD {5875, 6005, 0}
+1 -1
View File
@@ -65,7 +65,7 @@ class RealmList
private: private:
void UpdateRealms(bool init); void UpdateRealms(bool init);
void UpdateRealm(uint32 ID, const std::string& name, const std::string& address, uint32 port, uint8 icon, uint8 color, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build); void UpdateRealm(uint32 ID, const std::string& name, const std::string& address, uint32 port, uint8 icon, uint8 color, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build);
private:
RealmMap m_realms; ///< Internal map of realms RealmMap m_realms; ///< Internal map of realms
uint32 m_UpdateInterval; uint32 m_UpdateInterval;
time_t m_NextUpdateTime; time_t m_NextUpdateTime;
+57 -68
View File
@@ -30,18 +30,15 @@
#include "AuthCodes.h" #include "AuthCodes.h"
#include <openssl/md5.h> #include <openssl/md5.h>
#include "SHA1.h" #include "SHA1.h"
//#include "Util.h" -- for commented utf8ToUpperOnlyLatin
#define ChunkSize 2048 #define ChunkSize 2048
enum eAuthCmd enum eAuthCmd
{ {
//AUTH_NO_CMD = 0xFF,
AUTH_LOGON_CHALLENGE = 0x00, AUTH_LOGON_CHALLENGE = 0x00,
AUTH_LOGON_PROOF = 0x01, AUTH_LOGON_PROOF = 0x01,
AUTH_RECONNECT_CHALLENGE = 0x02, AUTH_RECONNECT_CHALLENGE = 0x02,
AUTH_RECONNECT_PROOF = 0x03, AUTH_RECONNECT_PROOF = 0x03,
//update srv =4
REALM_LIST = 0x10, REALM_LIST = 0x10,
XFER_INITIATE = 0x30, XFER_INITIATE = 0x30,
XFER_DATA = 0x31, XFER_DATA = 0x31,
@@ -107,9 +104,7 @@ typedef struct AUTH_LOGON_PROOF_S_OLD
uint8 cmd; uint8 cmd;
uint8 error; uint8 error;
uint8 M2[20]; uint8 M2[20];
//uint32 unk1;
uint32 unk2; uint32 unk2;
//uint16 unk3;
} sAuthLogonProof_S_Old; } sAuthLogonProof_S_Old;
typedef struct AUTH_RECONNECT_PROOF_C typedef struct AUTH_RECONNECT_PROOF_C
@@ -314,7 +309,10 @@ bool AuthSocket::_HandleLogonChallenge()
socket().recv((char *)&buf[0], 4); socket().recv((char *)&buf[0], 4);
#if TRINITY_ENDIAN == TRINITY_BIGENDIAN
EndianConvert(*((uint16*)(buf[0]))); EndianConvert(*((uint16*)(buf[0])));
#endif
uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size; uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size;
sLog.outStaticDebug("[AuthChallenge] got header, body is %#04x bytes", remaining); sLog.outStaticDebug("[AuthChallenge] got header, body is %#04x bytes", remaining);
@@ -333,6 +331,7 @@ bool AuthSocket::_HandleLogonChallenge()
// BigEndian code, nop in little endian case // BigEndian code, nop in little endian case
// size already converted // size already converted
#if TRINITY_ENDIAN == TRINITY_BIGENDIAN
EndianConvert(*((uint32*)(&ch->gamename[0]))); EndianConvert(*((uint32*)(&ch->gamename[0])));
EndianConvert(ch->build); EndianConvert(ch->build);
EndianConvert(*((uint32*)(&ch->platform[0]))); EndianConvert(*((uint32*)(&ch->platform[0])));
@@ -340,29 +339,28 @@ bool AuthSocket::_HandleLogonChallenge()
EndianConvert(*((uint32*)(&ch->country[0]))); EndianConvert(*((uint32*)(&ch->country[0])));
EndianConvert(ch->timezone_bias); EndianConvert(ch->timezone_bias);
EndianConvert(ch->ip); EndianConvert(ch->ip);
#endif
ByteBuffer pkt; ByteBuffer pkt;
_login = (const char*)ch->I; _login = (const char*)ch->I;
_build = ch->build; _build = ch->build;
_expversion = (AuthHelper::IsPostBCAcceptedClientBuild(_build) ? POST_BC_EXP_FLAG : NO_VALID_EXP_FLAG) + (AuthHelper::IsPreBCAcceptedClientBuild(_build) ? PRE_BC_EXP_FLAG : NO_VALID_EXP_FLAG); _expversion = (AuthHelper::IsPostBCAcceptedClientBuild(_build) ? POST_BC_EXP_FLAG : NO_VALID_EXP_FLAG) | (AuthHelper::IsPreBCAcceptedClientBuild(_build) ? PRE_BC_EXP_FLAG : NO_VALID_EXP_FLAG);
pkt << (uint8) AUTH_LOGON_CHALLENGE; pkt << (uint8)AUTH_LOGON_CHALLENGE;
pkt << (uint8) 0x00; pkt << (uint8)0x00;
// Verify that this IP is not in the ip_banned table // Verify that this IP is not in the ip_banned table
LoginDatabase.Execute( LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_SET_EXPIREDIPBANS));
LoginDatabase.GetPreparedStatement(LOGIN_SET_EXPIREDIPBANS)
);
const std::string& ip_address = socket().get_remote_address(); const std::string& ip_address = socket().get_remote_address();
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_IPBANNED); PreparedStatement *stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_IPBANNED);
stmt->setString(0, ip_address); stmt->setString(0, ip_address);
PreparedQueryResult result = LoginDatabase.Query(stmt); PreparedQueryResult result = LoginDatabase.Query(stmt);
if (result) if (result)
{ {
pkt << (uint8)WOW_FAIL_BANNED; pkt << (uint8)WOW_FAIL_BANNED;
sLog.outBasic("[AuthChallenge] Banned ip %s tries to login!", ip_address.c_str()); sLog.outBasic("[AuthChallenge] Banned ip %s tried to login!", ip_address.c_str());
} }
else else
{ {
@@ -387,7 +385,7 @@ bool AuthSocket::_HandleLogonChallenge()
{ {
sLog.outStaticDebug("[AuthChallenge] Account IP differs"); sLog.outStaticDebug("[AuthChallenge] Account IP differs");
pkt << (uint8) WOW_FAIL_SUSPENDED; pkt << (uint8) WOW_FAIL_SUSPENDED;
locked=true; locked = true;
} }
else else
sLog.outStaticDebug("[AuthChallenge] Account IP matches"); sLog.outStaticDebug("[AuthChallenge] Account IP matches");
@@ -398,9 +396,7 @@ bool AuthSocket::_HandleLogonChallenge()
if (!locked) if (!locked)
{ {
//set expired bans to inactive //set expired bans to inactive
LoginDatabase.Execute( LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_SET_EXPIREDACCBANS));
LoginDatabase.GetPreparedStatement(LOGIN_SET_EXPIREDACCBANS)
);
// If the account is banned, reject the logon attempt // If the account is banned, reject the logon attempt
stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_ACCBANNED); stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_ACCBANNED);
@@ -410,13 +406,13 @@ bool AuthSocket::_HandleLogonChallenge()
{ {
if ((*banresult)[0].GetUInt64() == (*banresult)[1].GetUInt64()) if ((*banresult)[0].GetUInt64() == (*banresult)[1].GetUInt64())
{ {
pkt << (uint8) WOW_FAIL_BANNED; pkt << (uint8)WOW_FAIL_BANNED;
sLog.outBasic("[AuthChallenge] Banned account %s tries to login!", _login.c_str()); sLog.outBasic("[AuthChallenge] Banned account %s tried to login!", _login.c_str());
} }
else else
{ {
pkt << (uint8) WOW_FAIL_SUSPENDED; pkt << (uint8)WOW_FAIL_SUSPENDED;
sLog.outBasic("[AuthChallenge] Temporarily banned account %s tries to login!", _login.c_str()); sLog.outBasic("[AuthChallenge] Temporarily banned account %s tried to login!", _login.c_str());
} }
} }
else else
@@ -430,8 +426,8 @@ bool AuthSocket::_HandleLogonChallenge()
sLog.outDebug("database authentication values: v='%s' s='%s'", databaseV.c_str(), databaseS.c_str()); sLog.outDebug("database authentication values: v='%s' s='%s'", databaseV.c_str(), databaseS.c_str());
// multiply with 2, bytes are stored as hexstring // multiply with 2 since bytes are stored as hexstring
if (databaseV.size() != s_BYTE_SIZE*2 || databaseS.size() != s_BYTE_SIZE*2) if (databaseV.size() != s_BYTE_SIZE * 2 || databaseS.size() != s_BYTE_SIZE * 2)
_SetVSFields(rI); _SetVSFields(rI);
else else
{ {
@@ -494,7 +490,7 @@ bool AuthSocket::_HandleLogonChallenge()
} }
} }
else //no account else //no account
pkt<< (uint8) WOW_FAIL_UNKNOWN_ACCOUNT; pkt << (uint8)WOW_FAIL_UNKNOWN_ACCOUNT;
} }
socket().send((char const*)pkt.contents(), pkt.size()); socket().send((char const*)pkt.contents(), pkt.size());
@@ -525,7 +521,7 @@ bool AuthSocket::_HandleLogonProof()
A.SetBinary(lp.A, 32); A.SetBinary(lp.A, 32);
// SRP safeguard: abort if A==0 // SRP safeguard: abort if A == 0
if (A.isZero()) if (A.isZero())
{ {
socket().shutdown(); socket().shutdown();
@@ -619,7 +615,7 @@ bool AuthSocket::_HandleLogonProof()
sha.UpdateBigNumbers(&A, &M, &K, NULL); sha.UpdateBigNumbers(&A, &M, &K, NULL);
sha.Finalize(); sha.Finalize();
if (_expversion & POST_BC_EXP_FLAG) // 2.4.3 and 3.1.3 clients (10146 is Chinese build for 3.1.3) if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients
{ {
sAuthLogonProof_S proof; sAuthLogonProof_S proof;
memcpy(proof.M2, sha.GetDigest(), 20); memcpy(proof.M2, sha.GetDigest(), 20);
@@ -636,13 +632,10 @@ bool AuthSocket::_HandleLogonProof()
memcpy(proof.M2, sha.GetDigest(), 20); memcpy(proof.M2, sha.GetDigest(), 20);
proof.cmd = AUTH_LOGON_PROOF; proof.cmd = AUTH_LOGON_PROOF;
proof.error = 0; proof.error = 0;
//proof.unk1 = 0x00800000;
proof.unk2 = 0x00; proof.unk2 = 0x00;
//proof.unk3 = 0x00;
socket().send((char *)&proof, sizeof(proof)); socket().send((char *)&proof, sizeof(proof));
} }
// Set _authed to true!
_authed = true; _authed = true;
} }
else else
@@ -656,7 +649,7 @@ bool AuthSocket::_HandleLogonProof()
if (MaxWrongPassCount > 0) if (MaxWrongPassCount > 0)
{ {
//Increment number of failed logins by one and if it reaches the limit temporarily ban that account or IP //Increment number of failed logins by one and if it reaches the limit temporarily ban that account or IP
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SET_FAILEDLOGINS); PreparedStatement *stmt = LoginDatabase.GetPreparedStatement(LOGIN_SET_FAILEDLOGINS);
stmt->setString(0, _login); stmt->setString(0, _login);
LoginDatabase.Execute(stmt); LoginDatabase.Execute(stmt);
@@ -714,7 +707,10 @@ bool AuthSocket::_HandleReconnectChallenge()
socket().recv((char *)&buf[0], 4); socket().recv((char *)&buf[0], 4);
#if TRINITY_ENDIAN == TRINITY_BIGENDIAN
EndianConvert(*((uint16*)(buf[0]))); EndianConvert(*((uint16*)(buf[0])));
#endif
uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size; uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size;
sLog.outStaticDebug("[ReconnectChallenge] got header, body is %#04x bytes", remaining); sLog.outStaticDebug("[ReconnectChallenge] got header, body is %#04x bytes", remaining);
@@ -749,11 +745,11 @@ bool AuthSocket::_HandleReconnectChallenge()
// Sending response // Sending response
ByteBuffer pkt; ByteBuffer pkt;
pkt << (uint8) AUTH_RECONNECT_CHALLENGE; pkt << (uint8)AUTH_RECONNECT_CHALLENGE;
pkt << (uint8) 0x00; pkt << (uint8)0x00;
_reconnectProof.SetRand(16 * 8); _reconnectProof.SetRand(16 * 8);
pkt.append(_reconnectProof.AsByteArray(16), 16); // 16 bytes random pkt.append(_reconnectProof.AsByteArray(16), 16); // 16 bytes random
pkt << (uint64) 0x00 << (uint64) 0x00; // 16 bytes zeros pkt << (uint64)0x00 << (uint64)0x00; // 16 bytes zeros
socket().send((char const*)pkt.contents(), pkt.size()); socket().send((char const*)pkt.contents(), pkt.size());
return true; return true;
} }
@@ -783,14 +779,11 @@ bool AuthSocket::_HandleReconnectProof()
{ {
// Sending response // Sending response
ByteBuffer pkt; ByteBuffer pkt;
pkt << (uint8) AUTH_RECONNECT_PROOF; pkt << (uint8)AUTH_RECONNECT_PROOF;
pkt << (uint8) 0x00; pkt << (uint8)0x00;
pkt << (uint16) 0x00; // 2 bytes zeros pkt << (uint16)0x00; // 2 bytes zeros
socket().send((char const*)pkt.contents(), pkt.size()); socket().send((char const*)pkt.contents(), pkt.size());
// Set _authed to true!
_authed = true; _authed = true;
return true; return true;
} }
else else
@@ -812,7 +805,6 @@ bool AuthSocket::_HandleRealmList()
// Get the user id (else close the connection) // Get the user id (else close the connection)
// No SQL injection (prepared statement) // No SQL injection (prepared statement)
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_ACCIDBYNAME); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_ACCIDBYNAME);
stmt->setString(0, _login); stmt->setString(0, _login);
PreparedQueryResult result = LoginDatabase.Query(stmt); PreparedQueryResult result = LoginDatabase.Query(stmt);
@@ -836,16 +828,10 @@ bool AuthSocket::_HandleRealmList()
for (RealmList::RealmMap::const_iterator i = sRealmList->begin(); i != sRealmList->end(); ++i) for (RealmList::RealmMap::const_iterator i = sRealmList->begin(); i != sRealmList->end(); ++i)
{ {
// don't work with realms which not compatible with the client // don't work with realms which not compatible with the client
if (_expversion & POST_BC_EXP_FLAG) // 2.4.3 and 3.1.3 cliens if ((_expversion & POST_BC_EXP_FLAG) && i->second.gamebuild != _build)
{ continue;
if (i->second.gamebuild != _build) else if ((_expversion & PRE_BC_EXP_FLAG) && !AuthHelper::IsPreBCAcceptedClientBuild(i->second.gamebuild))
continue; continue;
}
else if (_expversion & PRE_BC_EXP_FLAG) // 1.12.1 and 1.12.2 clients are compatible with eachother
{
if (!AuthHelper::IsPreBCAcceptedClientBuild(i->second.gamebuild))
continue;
}
uint8 AmountOfCharacters; uint8 AmountOfCharacters;
@@ -862,7 +848,7 @@ bool AuthSocket::_HandleRealmList()
uint8 lock = (i->second.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; uint8 lock = (i->second.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0;
pkt << i->second.icon; // realm type pkt << i->second.icon; // realm type
if ( _expversion & POST_BC_EXP_FLAG ) // only 2.4.3 and 3.1.3 cliens if ( _expversion & POST_BC_EXP_FLAG ) // only 2.x and 3.x clients
pkt << lock; // if 1, then realm locked pkt << lock; // if 1, then realm locked
pkt << i->second.color; // if 2, then realm is offline pkt << i->second.color; // if 2, then realm is offline
pkt << i->first; pkt << i->first;
@@ -870,29 +856,29 @@ bool AuthSocket::_HandleRealmList()
pkt << i->second.populationLevel; pkt << i->second.populationLevel;
pkt << AmountOfCharacters; pkt << AmountOfCharacters;
pkt << i->second.timezone; // realm category pkt << i->second.timezone; // realm category
if ( _expversion & POST_BC_EXP_FLAG ) // 2.4.3 and 3.1.3 clients if ( _expversion & POST_BC_EXP_FLAG ) // 2.x and 3.x clients
pkt << (uint8) 0x2C; // unk, may be realm number/id? pkt << (uint8)0x2C; // unk, may be realm number/id?
else else
pkt << (uint8) 0x0; // 1.12.1 and 1.12.2 clients pkt << (uint8)0x0; // 1.12.1 and 1.12.2 clients
++RealmListSize; ++RealmListSize;
} }
if ( _expversion & POST_BC_EXP_FLAG ) // 2.4.3 and 3.1.3 cliens if ( _expversion & POST_BC_EXP_FLAG ) // 2.x and 3.x clients
{ {
pkt << (uint8) 0x10; pkt << (uint8)0x10;
pkt << (uint8) 0x00; pkt << (uint8)0x00;
} }
else // 1.12.1 and 1.12.2 clients else // 1.12.1 and 1.12.2 clients
{ {
pkt << (uint8) 0x00; pkt << (uint8)0x00;
pkt << (uint8) 0x02; pkt << (uint8)0x02;
} }
// make a ByteBuffer which stores the RealmList's size // make a ByteBuffer which stores the RealmList's size
ByteBuffer RealmListSizeBuffer; ByteBuffer RealmListSizeBuffer;
RealmListSizeBuffer << (uint32)0; RealmListSizeBuffer << (uint32)0;
if (_expversion & POST_BC_EXP_FLAG) // only 2.4.3 and 3.1.3 clients if (_expversion & POST_BC_EXP_FLAG) // only 2.x and 3.x clients
RealmListSizeBuffer << (uint16)RealmListSize; RealmListSizeBuffer << (uint16)RealmListSize;
else else
RealmListSizeBuffer << (uint32)RealmListSize; RealmListSizeBuffer << (uint32)RealmListSize;
@@ -979,8 +965,10 @@ void Patcher::LoadPatchesInfo()
//int errno; //int errno;
struct dirent * dp; struct dirent * dp;
dirp = opendir("./patches/"); dirp = opendir("./patches/");
if (!dirp) if (!dirp)
return; return;
while (dirp) while (dirp)
{ {
errno = 0; errno = 0;
@@ -989,7 +977,7 @@ void Patcher::LoadPatchesInfo()
int l = strlen(dp->d_name); int l = strlen(dp->d_name);
if (l < 8) if (l < 8)
continue; continue;
if (!memcmp(&dp->d_name[l-4],".mpq",4)) if (!memcmp(&dp->d_name[l - 4], ".mpq", 4))
LoadPatchMD5(dp->d_name); LoadPatchMD5(dp->d_name);
} }
else else
@@ -1019,12 +1007,12 @@ void Patcher::LoadPatchesInfo()
{ {
LoadPatchMD5(fil.cFileName); LoadPatchMD5(fil.cFileName);
} }
while(FindNextFile(hFil, &fil)); while (FindNextFile(hFil, &fil));
} }
#endif #endif
// Calculate and store MD5 hash for a given patch file // Calculate and store MD5 hash for a given patch file
void Patcher::LoadPatchMD5(char * szFileName) void Patcher::LoadPatchMD5(char *szFileName)
{ {
// Try to open the patch file // Try to open the patch file
std::string path = "./patches/"; std::string path = "./patches/";
@@ -1041,13 +1029,14 @@ void Patcher::LoadPatchMD5(char * szFileName)
// Calculate the MD5 hash // Calculate the MD5 hash
MD5_CTX ctx; MD5_CTX ctx;
MD5_Init(&ctx); MD5_Init(&ctx);
uint8* buf = new uint8[512*1024]; uint8* buf = new uint8[512 * 1024];
while (!feof(pPatch)) while (!feof(pPatch))
{ {
size_t read = fread(buf, 1, 512*1024, pPatch); size_t read = fread(buf, 1, 512 * 1024, pPatch);
MD5_Update(&ctx, buf, read); MD5_Update(&ctx, buf, read);
} }
delete [] buf; delete [] buf;
fclose(pPatch); fclose(pPatch);
@@ -1061,10 +1050,10 @@ bool Patcher::GetHash(char * pat, uint8 mymd5[16])
{ {
for (Patches::iterator i = _patches.begin(); i != _patches.end(); ++i) for (Patches::iterator i = _patches.begin(); i != _patches.end(); ++i)
if (!stricmp(pat, i->first.c_str())) if (!stricmp(pat, i->first.c_str()))
{ {
memcpy(mymd5, i->second->md5, 16); memcpy(mymd5, i->second->md5, 16);
return true; return true;
} }
return false; return false;
} }