diff options
Diffstat (limited to 'src/server')
-rw-r--r-- | src/server/authserver/Authentication/AuthCodes.cpp | 56 | ||||
-rwxr-xr-x | src/server/authserver/Authentication/AuthCodes.h | 18 | ||||
-rw-r--r-- | src/server/authserver/Server/AuthSocket.cpp | 81 | ||||
-rwxr-xr-x | src/server/authserver/Server/AuthSocket.h | 1 |
4 files changed, 128 insertions, 28 deletions
diff --git a/src/server/authserver/Authentication/AuthCodes.cpp b/src/server/authserver/Authentication/AuthCodes.cpp index 7a97cbee3de..bdb96ca0d25 100644 --- a/src/server/authserver/Authentication/AuthCodes.cpp +++ b/src/server/authserver/Authentication/AuthCodes.cpp @@ -16,17 +16,65 @@ */ #include "AuthCodes.h" +#include <cstddef> namespace AuthHelper { - bool IsAcceptedClientBuild(int build) + static RealmBuildInfo const PostBcAcceptedClientBuilds[] = + { + {15595, 4, 3, 4, ' '}, + {14545, 4, 2, 2, ' '}, + {13623, 4, 0, 6, 'a'}, + {12340, 3, 3, 5, 'a'}, + {11723, 3, 3, 3, 'a'}, + {11403, 3, 3, 2, ' '}, + {11159, 3, 3, 0, 'a'}, + {10505, 3, 2, 2, 'a'}, + {9947, 3, 1, 3, ' '}, + {8606, 2, 4, 3, ' '}, + {0, 0, 0, 0, ' '} // terminator + }; + + static RealmBuildInfo const PreBcAcceptedClientBuilds[] = + { + {6005, 1, 12, 2, ' '}, + {5875, 1, 12, 1, ' '}, + {0, 0, 0, 0, ' '} // terminator + }; + + bool IsPreBCAcceptedClientBuild(int build) { - static int accepted_versions[] = TRINITYCORE_ACCEPTED_CLIENT_BUILD; + for (int i = 0; PreBcAcceptedClientBuilds[i].Build; ++i) + if (PreBcAcceptedClientBuilds[i].Build == build) + return true; - for (int i = 0; accepted_versions[i]; ++i) - if (build == accepted_versions[i]) + return false; + } + + bool IsPostBCAcceptedClientBuild(int build) + { + for (int i = 0; PostBcAcceptedClientBuilds[i].Build; ++i) + if (PostBcAcceptedClientBuilds[i].Build == build) return true; return false; } + + bool IsAcceptedClientBuild(int build) + { + return (IsPostBCAcceptedClientBuild(build) || IsPreBCAcceptedClientBuild(build)); + } + + RealmBuildInfo const* GetBuildInfo(int build) + { + for (int i = 0; PostBcAcceptedClientBuilds[i].Build; ++i) + if (PostBcAcceptedClientBuilds[i].Build == build) + return &PostBcAcceptedClientBuilds[i]; + + for (int i = 0; PreBcAcceptedClientBuilds[i].Build; ++i) + if (PreBcAcceptedClientBuilds[i].Build == build) + return &PreBcAcceptedClientBuilds[i]; + + return NULL; + } }; diff --git a/src/server/authserver/Authentication/AuthCodes.h b/src/server/authserver/Authentication/AuthCodes.h index 9d631a5800d..148225377ff 100755 --- a/src/server/authserver/Authentication/AuthCodes.h +++ b/src/server/authserver/Authentication/AuthCodes.h @@ -65,12 +65,28 @@ enum LoginResult LOGIN_LOCKED_ENFORCED = 0x10, }; -#define TRINITYCORE_ACCEPTED_CLIENT_BUILD {15595, 12340, 0} // accept one Cataclysm and one Wrath of the Lich King build +enum ExpansionFlags +{ + POST_BC_EXP_FLAG = 0x2, + PRE_BC_EXP_FLAG = 0x1, + NO_VALID_EXP_FLAG = 0x0 +}; +struct RealmBuildInfo +{ + int Build; + int MajorVersion; + int MinorVersion; + int BugfixVersion; + int HotfixVersion; +}; namespace AuthHelper { + RealmBuildInfo const* GetBuildInfo(int build); bool IsAcceptedClientBuild(int build); + bool IsPostBCAcceptedClientBuild(int build); + bool IsPreBCAcceptedClientBuild(int build); }; #endif diff --git a/src/server/authserver/Server/AuthSocket.cpp b/src/server/authserver/Server/AuthSocket.cpp index 793f310f8c1..2ad80c7f62d 100644 --- a/src/server/authserver/Server/AuthSocket.cpp +++ b/src/server/authserver/Server/AuthSocket.cpp @@ -389,7 +389,7 @@ bool AuthSocket::_HandleLogonChallenge() if (strcmp(fields[3].GetCString(), ip_address.c_str())) { sLog->outDebug(LOG_FILTER_AUTHSERVER, "[AuthChallenge] Account IP differs"); - pkt << uint8(WOW_FAIL_SUSPENDED); + pkt << (uint8) WOW_FAIL_SUSPENDED; locked = true; } else @@ -450,10 +450,7 @@ bool AuthSocket::_HandleLogonChallenge() unk3.SetRand(16 * 8); // Fill the response packet with the result - // If the client has no valid version - if (!AuthHelper::IsAcceptedClientBuild(_build)) - pkt << uint8(WOW_FAIL_VERSION_INVALID); - else + if (AuthHelper::IsAcceptedClientBuild(_build)) pkt << uint8(WOW_SUCCESS); else pkt << uint8(WOW_FAIL_VERSION_INVALID); @@ -501,7 +498,7 @@ bool AuthSocket::_HandleLogonChallenge() } } else //no account - pkt << uint8(WOW_FAIL_UNKNOWN_ACCOUNT); + pkt << (uint8)WOW_FAIL_UNKNOWN_ACCOUNT; } socket().send((char const*)pkt.contents(), pkt.size()); @@ -518,6 +515,15 @@ bool AuthSocket::_HandleLogonProof() if (!socket().recv((char *)&lp, sizeof(sAuthLogonProof_C))) return false; + // If the client has no valid version + if (_expversion == NO_VALID_EXP_FLAG) + { + // Check if we have the appropriate patch on the disk + sLog->outDebug(LOG_FILTER_NETWORKIO, "Client with invalid version, patching is not implemented"); + socket().shutdown(); + return true; + } + // Continue the SRP6 calculation based on data received from the client BigNumber A; @@ -618,14 +624,26 @@ bool AuthSocket::_HandleLogonProof() sha.UpdateBigNumbers(&A, &M, &K, NULL); sha.Finalize(); - sAuthLogonProof_S proof; - memcpy(proof.M2, sha.GetDigest(), 20); - proof.cmd = AUTH_LOGON_PROOF; - proof.error = 0; - proof.unk1 = 0x00800000; // Accountflags. 0x01 = GM, 0x08 = Trial, 0x00800000 = Pro pass (arena tournament) - proof.unk2 = 0x00; // SurveyId - proof.unk3 = 0x00; - socket().send((char *)&proof, sizeof(proof)); + if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients + { + sAuthLogonProof_S proof; + memcpy(proof.M2, sha.GetDigest(), 20); + proof.cmd = AUTH_LOGON_PROOF; + proof.error = 0; + proof.unk1 = 0x00800000; // Accountflags. 0x01 = GM, 0x08 = Trial, 0x00800000 = Pro pass (arena tournament) + proof.unk2 = 0x00; // SurveyId + proof.unk3 = 0x00; + socket().send((char *)&proof, sizeof(proof)); + } + else + { + sAuthLogonProof_S_Old proof; + memcpy(proof.M2, sha.GetDigest(), 20); + proof.cmd = AUTH_LOGON_PROOF; + proof.error = 0; + proof.unk2 = 0x00; + socket().send((char *)&proof, sizeof(proof)); + } _authed = true; } @@ -734,6 +752,7 @@ bool AuthSocket::_HandleReconnectChallenge() // Reinitialize build, expansion and the account securitylevel _build = ch->build; + _expversion = uint8(AuthHelper::IsPostBCAcceptedClientBuild(_build) ? POST_BC_EXP_FLAG : (AuthHelper::IsPreBCAcceptedClientBuild(_build) ? PRE_BC_EXP_FLAG : NO_VALID_EXP_FLAG)); _os = (const char*)ch->os; if (_os.size() > 4) @@ -833,13 +852,15 @@ bool AuthSocket::_HandleRealmList() for (RealmList::RealmMap::const_iterator i = sRealmList->begin(); i != sRealmList->end(); ++i) { // don't work with realms which not compatible with the client - if (i->second.gamebuild != _build) + bool okBuild = ((_expversion & POST_BC_EXP_FLAG) && i->second.gamebuild == _build) || ((_expversion & PRE_BC_EXP_FLAG) && !AuthHelper::IsPreBCAcceptedClientBuild(i->second.gamebuild)); + + // No SQL injection. id of realm is controlled by the database. uint32 flag = i->second.flag; RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(i->second.gamebuild); if (!okBuild) { if (!buildInfo) - continue; + continue; flag |= REALM_FLAG_OFFLINE | REALM_FLAG_SPECIFYBUILD; // tell the client what build the realm is for } @@ -866,14 +887,18 @@ bool AuthSocket::_HandleRealmList() AmountOfCharacters = (*result)[0].GetUInt8(); pkt << i->second.icon; // realm type - pkt << lock; // if 1, then realm locked + if (_expversion & POST_BC_EXP_FLAG) // only 2.x and 3.x clients + pkt << lock; // if 1, then realm locked pkt << uint8(flag); // RealmFlags pkt << name; pkt << i->second.address; pkt << i->second.populationLevel; pkt << AmountOfCharacters; pkt << i->second.timezone; // realm category - pkt << uint8(0x2C); // unk, may be realm number/id? + if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients + pkt << uint8(0x2C); // unk, may be realm number/id? + else + pkt << uint8(0x0); // 1.12.1 and 1.12.2 clients if (_expversion & POST_BC_EXP_FLAG && flag & REALM_FLAG_SPECIFYBUILD) { @@ -886,18 +911,28 @@ bool AuthSocket::_HandleRealmList() ++RealmListSize; } - pkt << uint8(0x10); - pkt << uint8(0x00); - + if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients + { + pkt << uint8(0x10); + pkt << uint8(0x00); + } + else // 1.12.1 and 1.12.2 clients + { + pkt << uint8(0x00); + pkt << uint8(0x02); + } // make a ByteBuffer which stores the RealmList's size ByteBuffer RealmListSizeBuffer; RealmListSizeBuffer << uint32(0); - RealmListSizeBuffer << uint16(RealmListSize); + if (_expversion & POST_BC_EXP_FLAG) // only 2.x and 3.x clients + RealmListSizeBuffer << uint16(RealmListSize); + else + RealmListSizeBuffer << uint32(RealmListSize); ByteBuffer hdr; hdr << uint8(REALM_LIST); - hdr << uint16((pkt.size() + RealmListSizeBuffer.size())); + hdr << uint16(pkt.size() + RealmListSizeBuffer.size()); hdr.append(RealmListSizeBuffer); // append RealmList's size buffer hdr.append(pkt); // append realms in the realmlist diff --git a/src/server/authserver/Server/AuthSocket.h b/src/server/authserver/Server/AuthSocket.h index edd2b345183..9be2136b55c 100755 --- a/src/server/authserver/Server/AuthSocket.h +++ b/src/server/authserver/Server/AuthSocket.h @@ -70,6 +70,7 @@ private: std::string _localizationName; std::string _os; uint16 _build; + uint8 _expversion; AccountTypes _accountSecurityLevel; }; |