diff options
| -rw-r--r-- | src/server/authserver/Authentication/AuthCodes.h | 9 | ||||
| -rw-r--r-- | src/server/authserver/Server/BattlenetBitStream.h | 12 | ||||
| -rw-r--r-- | src/server/authserver/Server/BattlenetManager.cpp | 38 | ||||
| -rw-r--r-- | src/server/authserver/Server/BattlenetManager.h | 47 | ||||
| -rw-r--r-- | src/server/authserver/Server/BattlenetPackets.cpp | 33 | ||||
| -rw-r--r-- | src/server/authserver/Server/BattlenetPackets.h | 18 | ||||
| -rw-r--r-- | src/server/authserver/Server/BattlenetSocket.cpp | 34 | ||||
| -rw-r--r-- | src/server/authserver/Server/BattlenetSocket.h | 2 | ||||
| -rw-r--r-- | src/server/shared/Utilities/Util.cpp | 25 | ||||
| -rw-r--r-- | src/server/shared/Utilities/Util.h | 1 |
10 files changed, 179 insertions, 40 deletions
diff --git a/src/server/authserver/Authentication/AuthCodes.h b/src/server/authserver/Authentication/AuthCodes.h index e844863e4b1..12c2a810abb 100644 --- a/src/server/authserver/Authentication/AuthCodes.h +++ b/src/server/authserver/Authentication/AuthCodes.h @@ -97,7 +97,10 @@ namespace Battlenet AUTH_BATTLENET_MAINTENANCE = 122, AUTH_LOGON_TOO_FAST = 123, AUTH_USE_GRUNT_LOGON = 124, + AUTH_NO_GAME_ACCOUNTS_IN_REGION = 140, + AUTH_ACCOUNT_LOCKED = 141, + LOGIN_SERVER_BUSY = 200, LOGIN_NO_GAME_ACCOUNT = 201, LOGIN_BANNED = 202, LOGIN_SUSPENDED = 203, @@ -110,9 +113,9 @@ namespace Battlenet LOGIN_TRIAL_EXPIRED = 210, LOGIN_ANTI_INDULGENCE = 211, LOGIN_INCORRECT_REGION = 212, - LOGIN_CHARGEBACK = 213, - LOGIN_IGR_WITHOUT_BNET = 214, - LOGIN_LOCKED_ENFORCED = 215, + LOGIN_LOCKED_ENFORCED = 213, + LOGIN_CHARGEBACK = 214, + LOGIN_IGR_WITHOUT_BNET = 215, LOGIN_UNLOCKABLE_LOCK = 216, LOGIN_IGR_REQUIRED = 217, LOGIN_PAYMENT_CHANGED = 218, diff --git a/src/server/authserver/Server/BattlenetBitStream.h b/src/server/authserver/Server/BattlenetBitStream.h index 4b6c7f882d4..d372e0933c2 100644 --- a/src/server/authserver/Server/BattlenetBitStream.h +++ b/src/server/authserver/Server/BattlenetBitStream.h @@ -22,16 +22,21 @@ #include <exception> #include <string> #include <vector> +#include <ace/Stack_Trace.h> namespace Battlenet { class BitStreamPositionException : public std::exception { public: + BitStreamPositionException() : st(1) { } + char const* what() const { - return ""; + return st.c_str(); } + + ACE_Stack_Trace st; }; class BitStream @@ -121,7 +126,10 @@ namespace Battlenet void WriteBytes(T* data, uint32 count) { AlignToNextByte(); - if (_writePos + 8 * count > MaxSize) + if (!count || !data) + return; + + if (_writePos + count > MaxSize) throw BitStreamPositionException(); _buffer.resize(_buffer.size() + count); diff --git a/src/server/authserver/Server/BattlenetManager.cpp b/src/server/authserver/Server/BattlenetManager.cpp index b7df889809e..a43512e612e 100644 --- a/src/server/authserver/Server/BattlenetManager.cpp +++ b/src/server/authserver/Server/BattlenetManager.cpp @@ -18,6 +18,15 @@ #include "BattlenetManager.h" #include "DatabaseEnv.h" +BattlenetMgr::~BattlenetMgr() +{ + for (Battlenet::Component* component : _components) + delete component; + + for (auto const& m : _modules) + delete m.second; +} + void BattlenetMgr::Load() { LoadComponents(); @@ -40,7 +49,6 @@ void BattlenetMgr::LoadComponents() _components.insert(component); _programs.insert(component->Program); _platforms.insert(component->Platform); - _builds.insert(component->Build); } while (result->NextRow()); } @@ -48,7 +56,27 @@ void BattlenetMgr::LoadComponents() void BattlenetMgr::LoadModules() { + QueryResult result = LoginDatabase.Query("SELECT `Hash`, `Name`, `Type`, `System`, `Data` FROM battlenet_modules"); + if (result) + { + do + { + Field* fields = result->Fetch(); + Battlenet::ModuleInfo* module = new Battlenet::ModuleInfo(); + module->Type = fields[2].GetString(); + module->Region.assign("\0\0EU", 4); + HexStrToByteArray(fields[0].GetString(), module->ModuleId); + std::string data = fields[4].GetString(); + module->DataSize = data.length() / 2; + if (module->DataSize) + { + module->Data = new uint8[data.length() / 2]; + HexStrToByteArray(data, module->Data); + } + _modules[{ fields[3].GetString(), fields[1].GetString() }] = module; + } while (result->NextRow()); + } } bool BattlenetMgr::HasComponent(Battlenet::Component const* component) const @@ -59,3 +87,11 @@ bool BattlenetMgr::HasComponent(Battlenet::Component const* component) const return false; } + +Battlenet::ModuleInfo const* BattlenetMgr::GetModule(Battlenet::ModuleKey const& key) const +{ + if (_modules.count(key)) + return _modules.at(key); + + return NULL; +} diff --git a/src/server/authserver/Server/BattlenetManager.h b/src/server/authserver/Server/BattlenetManager.h index d3962a32c0d..9fceb973770 100644 --- a/src/server/authserver/Server/BattlenetManager.h +++ b/src/server/authserver/Server/BattlenetManager.h @@ -32,20 +32,61 @@ namespace Battlenet std::string Platform; uint32 Build; }; + + struct ModuleKey + { + std::string Platform; + std::string Name; + + bool operator<(ModuleKey const& right) const + { + int32 res = Platform.compare(right.Platform); + if (res < 0) + return true; + else if (res > 0) + return false; + + return Name < right.Name; + } + }; + + struct ModuleInfo + { + ModuleInfo() : DataSize(0), Data(nullptr) { } + ModuleInfo(ModuleInfo const& right) : Type(right.Type), Region(right.Region), DataSize(right.DataSize), Data(nullptr) + { + memcpy(ModuleId, right.ModuleId, 32); + if (DataSize) + { + Data = new uint8[DataSize]; + memcpy(Data, right.Data, DataSize); + } + } + ~ModuleInfo() + { + delete Data; + } + + std::string Type; + std::string Region; + uint8 ModuleId[32]; + uint32 DataSize; + uint8* Data; + }; } class BattlenetMgr { friend class ACE_Singleton<BattlenetMgr, ACE_Null_Mutex>; BattlenetMgr() { } - ~BattlenetMgr() { } + ~BattlenetMgr(); public: void Load(); bool HasComponent(Battlenet::Component const* component) const; bool HasProgram(std::string const& program) const { return _programs.count(program); } bool HasPlatform(std::string const& platform) const { return _platforms.count(platform); } - bool HasBuild(uint32 build) const { return _builds.count(build); } + Battlenet::ModuleInfo const* GetModule(Battlenet::ModuleKey const& key) const; private: void LoadComponents(); @@ -54,7 +95,7 @@ private: std::set<Battlenet::Component*> _components; std::set<std::string> _programs; std::set<std::string> _platforms; - std::set<uint32> _builds; + std::map<Battlenet::ModuleKey, Battlenet::ModuleInfo*> _modules; }; #define sBattlenetMgr ACE_Singleton<BattlenetMgr, ACE_Null_Mutex>::instance() diff --git a/src/server/authserver/Server/BattlenetPackets.cpp b/src/server/authserver/Server/BattlenetPackets.cpp index 80213a0ba33..68a602d8598 100644 --- a/src/server/authserver/Server/BattlenetPackets.cpp +++ b/src/server/authserver/Server/BattlenetPackets.cpp @@ -78,14 +78,13 @@ std::string Battlenet::AuthChallenge::ToString() const void Battlenet::ProofRequest::Write() { _stream.Write(Modules.size(), 3); - for (size_t i = 0; i < Modules.size(); ++i) + for (ModuleInfo const* info : Modules) { - ModuleInfo& info = Modules[i]; - _stream.WriteBytes(info.AuthString.c_str(), 4); - _stream.WriteFourCC(info.Locale.c_str()); - _stream.WriteBytes(info.ModuleId, 32); - _stream.Write(info.BlobSize, 10); - _stream.WriteBytes(info.Blob, info.BlobSize); + _stream.WriteBytes(info->Type.c_str(), 4); + _stream.WriteFourCC(info->Region.c_str()); + _stream.WriteBytes(info->ModuleId, 32); + _stream.Write(info->DataSize, 10); + _stream.WriteBytes(info->Data, info->DataSize); } } @@ -93,8 +92,8 @@ std::string Battlenet::ProofRequest::ToString() const { std::ostringstream stream; stream << "Battlenet::ProofRequest modules " << Modules.size(); - for (ModuleInfo const& module : Modules) - stream << std::endl << "Locale " << module.Locale << "ModuleId " << ByteArrayToHexStr(module.ModuleId, 32) << "BlobSize " << module.BlobSize; + for (ModuleInfo const* module : Modules) + stream << std::endl << "Locale " << module->Region << "ModuleId " << ByteArrayToHexStr(module->ModuleId, 32) << "BlobSize " << module->DataSize; return stream.str(); } @@ -138,11 +137,11 @@ void Battlenet::AuthComplete::Write() for (size_t i = 0; i < Modules.size(); ++i) { ModuleInfo& info = Modules[i]; - _stream.WriteBytes(info.AuthString.c_str(), 4); - _stream.WriteFourCC(info.Locale.c_str()); + _stream.WriteBytes(info.Type.c_str(), 4); + _stream.WriteFourCC(info.Region.c_str()); _stream.WriteBytes(info.ModuleId, 32); - _stream.Write(info.BlobSize, 10); - _stream.WriteBytes(info.Blob, info.BlobSize); + _stream.Write(info.DataSize, 10); + _stream.WriteBytes(info.Data, info.DataSize); } _stream.Write(PingTimeout + std::numeric_limits<int32>::min(), 32); @@ -165,11 +164,11 @@ void Battlenet::AuthComplete::Write() if (!Modules.empty()) { ModuleInfo& info = Modules[0]; - _stream.WriteBytes(info.AuthString.c_str(), 4); - _stream.WriteFourCC(info.Locale.c_str()); + _stream.WriteBytes(info.Type.c_str(), 4); + _stream.WriteFourCC(info.Region.c_str()); _stream.WriteBytes(info.ModuleId, 32); - _stream.Write(info.BlobSize, 10); - _stream.WriteBytes(info.Blob, info.BlobSize); + _stream.Write(info.DataSize, 10); + _stream.WriteBytes(info.Data, info.DataSize); } _stream.Write(ErrorType, 2); diff --git a/src/server/authserver/Server/BattlenetPackets.h b/src/server/authserver/Server/BattlenetPackets.h index 86dcb99a4da..3b02c0c602a 100644 --- a/src/server/authserver/Server/BattlenetPackets.h +++ b/src/server/authserver/Server/BattlenetPackets.h @@ -58,7 +58,12 @@ namespace Battlenet bool operator<(PacketHeader const& right) const { - return Opcode < right.Opcode || Channel < right.Channel; + if (Opcode < right.Opcode) + return true; + if (Opcode > right.Opcode) + return false; + + return Channel < right.Channel; } bool operator==(PacketHeader const& right) const @@ -133,15 +138,6 @@ namespace Battlenet std::string Login; }; - struct ModuleInfo - { - std::string AuthString; - std::string Locale; - uint8 ModuleId[32]; - uint32 BlobSize; - uint8* Blob; - }; - class ProofRequest final : public ServerPacket { public: @@ -150,7 +146,7 @@ namespace Battlenet void Write() override; std::string ToString() const override; - std::vector<ModuleInfo> Modules; + std::vector<ModuleInfo const*> Modules; }; class ProofResponse final : public ClientPacket diff --git a/src/server/authserver/Server/BattlenetSocket.cpp b/src/server/authserver/Server/BattlenetSocket.cpp index 04005e30878..edd73080270 100644 --- a/src/server/authserver/Server/BattlenetSocket.cpp +++ b/src/server/authserver/Server/BattlenetSocket.cpp @@ -25,6 +25,32 @@ bool Battlenet::Socket::HandleAuthChallenge(PacketHeader& header, BitStream& pac AuthChallenge info(header, packet); info.Read(); + printf("%s\n", info.ToString().c_str()); + + if (info.Program != "WoW") + { + AuthComplete complete; + complete.SetAuthResult(AUTH_INVALID_PROGRAM); + Send(complete); + return true; + } + + if (!sBattlenetMgr->HasPlatform(info.Platform)) + { + AuthComplete complete; + complete.SetAuthResult(AUTH_INVALID_OS); + Send(complete); + return true; + } + + if (!sBattlenetMgr->HasPlatform(info.Locale)) + { + AuthComplete complete; + complete.SetAuthResult(AUTH_UNSUPPORTED_LANGUAGE); + Send(complete); + return true; + } + for (Component const& component : info.Components) { if (!sBattlenetMgr->HasComponent(&component)) @@ -34,7 +60,7 @@ bool Battlenet::Socket::HandleAuthChallenge(PacketHeader& header, BitStream& pac complete.SetAuthResult(AUTH_INVALID_PROGRAM); else if (!sBattlenetMgr->HasPlatform(component.Platform)) complete.SetAuthResult(AUTH_INVALID_OS); - else if (!sBattlenetMgr->HasBuild(component.Build)) + else complete.SetAuthResult(AUTH_REGION_BAD_VERSION); Send(complete); @@ -42,9 +68,9 @@ bool Battlenet::Socket::HandleAuthChallenge(PacketHeader& header, BitStream& pac } } - printf("%s\n", info.ToString().c_str()); - _accountName = info.Login; + _locale = info.Locale; + _os = info.Platform; ProofRequest request; Send(request); @@ -101,6 +127,8 @@ void Battlenet::Socket::OnRead() header.Opcode = packet.Read<uint32>(6); if (packet.Read<uint32>(1)) _currentChannel = header.Channel = packet.Read<int32>(4); + else + header.Channel = _currentChannel; printf("Battlenet::Socket::OnRead %s\n", header.ToString().c_str()); std::map<PacketHeader, PacketHandler>::const_iterator itr = Handlers.find(header); diff --git a/src/server/authserver/Server/BattlenetSocket.h b/src/server/authserver/Server/BattlenetSocket.h index 7507f090a7f..b4db6c46251 100644 --- a/src/server/authserver/Server/BattlenetSocket.h +++ b/src/server/authserver/Server/BattlenetSocket.h @@ -48,6 +48,8 @@ namespace Battlenet uint32 _currentChannel; std::string _accountName; + std::string _locale; + std::string _os; PacketCrypt _crypt; }; diff --git a/src/server/shared/Utilities/Util.cpp b/src/server/shared/Utilities/Util.cpp index f2a6f1b7622..004335422c0 100644 --- a/src/server/shared/Utilities/Util.cpp +++ b/src/server/shared/Utilities/Util.cpp @@ -547,3 +547,28 @@ std::string ByteArrayToHexStr(uint8 const* bytes, uint32 arrayLen, bool reverse return ss.str(); } + +void HexStrToByteArray(std::string const& str, uint8* out, bool reverse /*= false*/) +{ + // string must have even number of characters + if (str.length() & 1) + return; + + int32 init = 0; + int32 end = str.length(); + int8 op = 1; + + if (reverse) + { + init = str.length() - 2; + end = -1; + op = -1; + } + + uint32 j = 0; + for (int32 i = init; i != end; i += 2 * op) + { + char buffer[3] = { str[i], str[i + 1], '\0' }; + out[j++] = strtoul(buffer, NULL, 16); + } +} diff --git a/src/server/shared/Utilities/Util.h b/src/server/shared/Utilities/Util.h index 236670e5cf1..d1cfeadff64 100644 --- a/src/server/shared/Utilities/Util.h +++ b/src/server/shared/Utilities/Util.h @@ -355,6 +355,7 @@ std::string GetAddressString(ACE_INET_Addr const& addr); uint32 CreatePIDFile(const std::string& filename); std::string ByteArrayToHexStr(uint8 const* bytes, uint32 length, bool reverse = false); +void HexStrToByteArray(std::string const& str, uint8* out, bool reverse = false); #endif //handler for operations on large flags |
