aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreeston <treeston.mmoc@gmail.com>2020-08-11 18:04:36 +0200
committerShauren <shauren.trinity@gmail.com>2022-01-26 19:42:11 +0100
commit319ddd9bcdeab13b07c992e05bef5698af090ee0 (patch)
tree1d4ebb9e0fadefbd6effdf1c10769e3488c94840
parentcf369301c42773d104121820a8d131bb502e81d8 (diff)
Core/Warden: Warden refactors (PR #25235)
(cherry picked from commit 6116e5b38522ccfb00f6c941c75482e05b4c0799)
-rw-r--r--sql/base/auth_database.sql3
-rw-r--r--sql/updates/auth/master/2020_08_11_00_auth.sql5
-rw-r--r--sql/updates/world/master/2022_01_26_31_world_2020_08_11_00_world_335.sql15
-rw-r--r--src/common/Utilities/Util.h9
-rw-r--r--src/server/game/Accounts/RBAC.h2
-rw-r--r--src/server/game/Server/WorldSession.cpp8
-rw-r--r--src/server/game/Warden/Modules/WardenModuleMac.h2
-rw-r--r--src/server/game/Warden/Modules/WardenModuleWin.h17
-rw-r--r--src/server/game/Warden/Warden.cpp166
-rw-r--r--src/server/game/Warden/Warden.h67
-rw-r--r--src/server/game/Warden/WardenCheckMgr.cpp95
-rw-r--r--src/server/game/Warden/WardenCheckMgr.h60
-rw-r--r--src/server/game/Warden/WardenMac.cpp67
-rw-r--r--src/server/game/Warden/WardenMac.h6
-rw-r--r--src/server/game/Warden/WardenWin.cpp295
-rw-r--r--src/server/game/Warden/WardenWin.h16
-rw-r--r--src/server/game/Warden/enuminfo_WardenCheckMgr.cpp100
-rw-r--r--src/server/scripts/Commands/cs_reload.cpp17
18 files changed, 503 insertions, 447 deletions
diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql
index 86f4ab20ae5..098319b982c 100644
--- a/sql/base/auth_database.sql
+++ b/sql/base/auth_database.sql
@@ -1193,7 +1193,6 @@ INSERT INTO `rbac_linked_permissions` VALUES
(196,702),
(196,703),
(196,704),
-(196,705),
(196,706),
(196,707),
(196,708),
@@ -2032,7 +2031,6 @@ INSERT INTO `rbac_permissions` VALUES
(702,'Command: reload spell_threats'),
(703,'Command: reload spell_group_stack_rules'),
(704,'Command: reload trinity_string'),
-(705,'Command: reload warden_action'),
(706,'Command: reload waypoint_scripts'),
(707,'Command: reload waypoint_data'),
(708,'Command: reload vehicle_accessory'),
@@ -2486,6 +2484,7 @@ INSERT INTO `updates` VALUES
('2020_08_03_01_auth.sql','EC1063396CA20A2303D83238470D41EF4439EC72','ARCHIVED','2020-08-03 00:00:01',0),
('2020_08_06_00_auth.sql','5D3C5B25132DAFCA3933E9CBE14F5E8A290C4AFA','ARCHIVED','2020-08-06 20:26:11',0),
('2020_08_08_00_auth.sql','BC6A08BE42A6F2C30C9286CBDD47D57B718C4635','ARCHIVED','2020-08-08 00:16:57',0),
+('2020_08_11_00_auth.sql','14C99177E43003D83A4D6F2227722F15FC15A1D0','ARCHIVED','2020-08-11 00:00:00',0),
('2020_08_14_00_auth.sql','DFB9B07A7846FC0E124EE4CC099E49FE5742FB66','ARCHIVED','2020-08-14 21:41:24',0),
('2020_08_26_00_auth.sql','D5EF787DECB41D898379588F101A0453B46F04D9','ARCHIVED','2020-08-26 21:00:34',0),
('2020_09_25_00_auth.sql','3CCA78EF89223724BA6784A4F3783DED30416637','ARCHIVED','2020-09-25 19:52:40',0),
diff --git a/sql/updates/auth/master/2020_08_11_00_auth.sql b/sql/updates/auth/master/2020_08_11_00_auth.sql
new file mode 100644
index 00000000000..16296ac7c90
--- /dev/null
+++ b/sql/updates/auth/master/2020_08_11_00_auth.sql
@@ -0,0 +1,5 @@
+--
+DELETE FROM `rbac_permissions` WHERE `id`=705;
+DELETE FROM `rbac_linked_permissions` WHERE `linkedId`=705;
+DELETE FROM `rbac_account_permissions` WHERE `permissionId`=705;
+DELETE FROM `rbac_default_permissions` WHERE `permissionId`=705;
diff --git a/sql/updates/world/master/2022_01_26_31_world_2020_08_11_00_world_335.sql b/sql/updates/world/master/2022_01_26_31_world_2020_08_11_00_world_335.sql
new file mode 100644
index 00000000000..6e66caa8855
--- /dev/null
+++ b/sql/updates/world/master/2022_01_26_31_world_2020_08_11_00_world_335.sql
@@ -0,0 +1,15 @@
+--
+ALTER TABLE `warden_checks`
+ CHANGE COLUMN `data` `oldData` VARCHAR(48),
+ CHANGE COLUMN `result` `oldResult` VARCHAR(24),
+ ADD COLUMN `data` BINARY(24) DEFAULT NULL,
+ ADD COLUMN `result` VARBINARY(12) DEFAULT NULL;
+
+UPDATE `warden_checks` SET `data`=UNHEX(`oldData`) WHERE `type` IN (113,178,191);
+UPDATE `warden_checks` SET `result`=UNHEX(`oldResult`) WHERE `type` IN (152,243);
+
+ALTER TABLE `warden_checks`
+ DROP COLUMN `oldData`,
+ DROP COLUMN `oldResult`;
+
+DELETE FROM `command` WHERE `name`='reload warden_action';
diff --git a/src/common/Utilities/Util.h b/src/common/Utilities/Util.h
index 18a380ea9b4..a7f6619838a 100644
--- a/src/common/Utilities/Util.h
+++ b/src/common/Utilities/Util.h
@@ -365,6 +365,15 @@ std::array<uint8, Size> HexStrToByteArray(std::string const& str, bool reverse =
return arr;
}
+inline std::vector<uint8> HexStrToByteVector(std::string const& str, bool reverse = false)
+{
+ std::vector<uint8> buf;
+ size_t const sz = (str.size() / 2);
+ buf.resize(sz);
+ Trinity::Impl::HexStrToByteArray(str, buf.data(), sz, reverse);
+ return buf;
+}
+
TC_COMMON_API bool StringToBool(std::string const& str);
TC_COMMON_API float DegToRad(float degrees);
diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h
index 355af8cb740..95f1df06e1b 100644
--- a/src/server/game/Accounts/RBAC.h
+++ b/src/server/game/Accounts/RBAC.h
@@ -610,7 +610,7 @@ enum RBACPermissions
RBAC_PERM_COMMAND_RELOAD_SPELL_THREATS = 702,
RBAC_PERM_COMMAND_RELOAD_SPELL_GROUP_STACK_RULES = 703,
RBAC_PERM_COMMAND_RELOAD_TRINITY_STRING = 704,
- RBAC_PERM_COMMAND_RELOAD_WARDEN_ACTION = 705,
+ // 705 unused
RBAC_PERM_COMMAND_RELOAD_WAYPOINT_SCRIPTS = 706,
RBAC_PERM_COMMAND_RELOAD_WAYPOINT_DATA = 707,
RBAC_PERM_COMMAND_RELOAD_VEHICLE_ACCESORY = 708,
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index ede413d824d..7d06c95b42a 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -475,7 +475,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
_recvQueue.readd(requeuePackets.begin(), requeuePackets.end());
if (m_Socket[CONNECTION_TYPE_REALM] && m_Socket[CONNECTION_TYPE_REALM]->IsOpen() && _warden)
- _warden->Update();
+ _warden->Update(diff);
if (!updater.ProcessUnsafe()) // <=> updater is of type MapSessionFilter
{
@@ -499,13 +499,13 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
if (ShouldLogOut(currentTime) && m_playerLoading.IsEmpty())
LogoutPlayer(true);
- if (m_Socket[CONNECTION_TYPE_REALM] && GetPlayer() && _warden)
- _warden->Update();
-
///- Cleanup socket pointer if need
if ((m_Socket[CONNECTION_TYPE_REALM] && !m_Socket[CONNECTION_TYPE_REALM]->IsOpen()) ||
(m_Socket[CONNECTION_TYPE_INSTANCE] && !m_Socket[CONNECTION_TYPE_INSTANCE]->IsOpen()))
{
+ if (GetPlayer() && _warden)
+ _warden->Update(diff);
+
expireTime -= expireTime > diff ? diff : expireTime;
if (expireTime < diff || forceExit || !GetPlayer())
{
diff --git a/src/server/game/Warden/Modules/WardenModuleMac.h b/src/server/game/Warden/Modules/WardenModuleMac.h
index 8efdf401b8c..a699261a284 100644
--- a/src/server/game/Warden/Modules/WardenModuleMac.h
+++ b/src/server/game/Warden/Modules/WardenModuleMac.h
@@ -18,7 +18,7 @@
#ifndef _WARDEN_MODULE_MAC_H
#define _WARDEN_MODULE_MAC_H
-uint8 Module_0DBBF209A27B1E279A9FEC5C168A15F7_Data[9318] =
+std::array<uint8, 9318> Module_0DBBF209A27B1E279A9FEC5C168A15F7_Data =
{
0x07, 0x0C, 0x44, 0xCD, 0xC9, 0xFB, 0x99, 0xBC, 0x7C, 0x77, 0xDC, 0xE8, 0x8D, 0x07, 0xBE, 0x55,
0x37, 0x5C, 0x84, 0x10, 0x23, 0xE1, 0x36, 0x5B, 0xF1, 0xBC, 0x60, 0xF3, 0x68, 0xBA, 0x60, 0x69,
diff --git a/src/server/game/Warden/Modules/WardenModuleWin.h b/src/server/game/Warden/Modules/WardenModuleWin.h
index d282e0090b5..faf9bf44d4e 100644
--- a/src/server/game/Warden/Modules/WardenModuleWin.h
+++ b/src/server/game/Warden/Modules/WardenModuleWin.h
@@ -18,22 +18,25 @@
#ifndef _WARDEN_MODULE_WIN_H
#define _WARDEN_MODULE_WIN_H
+#include "CryptoHash.h"
+#include <array>
+
/*
Seed: 4D808D2C77D905C41A6380EC08586AFE (0x05 packet)
Hash: 568C054C781A972A6037A2290C22B52571A06F4E (0x04 packet)
Module MD5: 79C0768D657977D697E10BAD956CCED1
New Client Key: 7F 96 EE FD A5 B6 3D 20 A4 DF 8E 00 CB F4 83 04
-New Cerver Key: C2 B7 AD ED FC CC A9 C2 BF B3 F8 56 02 BA 80 9B
+New Server Key: C2 B7 AD ED FC CC A9 C2 BF B3 F8 56 02 BA 80 9B
*/
struct Module_79C0768D657977D697E10BAD956CCED1
{
- uint8 Module[18756];
- uint8 ModuleKey[16];
- uint8 Seed[16];
- uint8 ServerKeySeed[16];
- uint8 ClientKeySeed[16];
- uint8 ClientKeySeedHash[20];
+ std::array<uint8, 18756> Module;
+ std::array<uint8, 16> ModuleKey;
+ std::array<uint8, 16> Seed;
+ std::array<uint8, 16> ServerKeySeed;
+ std::array<uint8, 16> ClientKeySeed;
+ Trinity::Crypto::SHA1::Digest ClientKeySeedHash;
} Module =
{
{
diff --git a/src/server/game/Warden/Warden.cpp b/src/server/game/Warden/Warden.cpp
index a938533ea5a..105460ca44b 100644
--- a/src/server/game/Warden/Warden.cpp
+++ b/src/server/game/Warden/Warden.cpp
@@ -29,23 +29,29 @@
#include "WardenPackets.h"
#include <openssl/sha.h>
+#include <openssl/md5.h>
-Warden::Warden() : _session(nullptr), _checkTimer(10000/*10 sec*/), _clientResponseTimer(0),
- _dataSent(false), _previousTimestamp(0), _module(nullptr), _initialized(false)
+Warden::Warden() : _session(nullptr), _checkTimer(10 * IN_MILLISECONDS), _clientResponseTimer(0),
+ _dataSent(false), _initialized(false)
{
- memset(_inputKey, 0, sizeof(_inputKey));
- memset(_outputKey, 0, sizeof(_outputKey));
- memset(_seed, 0, sizeof(_seed));
}
Warden::~Warden()
{
- delete[] _module->CompressedData;
- delete _module;
- _module = nullptr;
_initialized = false;
}
+void Warden::MakeModuleForClient()
+{
+ TC_LOG_DEBUG("warden", "Make module for client");
+ InitializeModuleForClient(_module.emplace());
+
+ MD5_CTX ctx;
+ MD5_Init(&ctx);
+ MD5_Update(&ctx, _module->CompressedData, _module->CompressedSize);
+ MD5_Final(_module->Id.data(), &ctx);
+}
+
void Warden::SendModuleToClient()
{
TC_LOG_DEBUG("warden", "Send module to client");
@@ -61,13 +67,15 @@ void Warden::SendModuleToClient()
burstSize = sizeLeft < 500 ? sizeLeft : 500;
packet.Command = WARDEN_SMSG_MODULE_CACHE;
packet.DataSize = burstSize;
- memcpy(packet.Data, &_module->CompressedData[pos], burstSize);
+ memcpy(packet.Data, _module->CompressedData + pos, burstSize);
sizeLeft -= burstSize;
pos += burstSize;
- EncryptData((uint8*)&packet, burstSize + 3);
+ EndianConvert(packet.DataSize);
+
+ EncryptData(reinterpret_cast<uint8*>(&packet), burstSize + 3);
WorldPacket pkt1(SMSG_WARDEN3_DATA, burstSize + 3);
- pkt1.append((uint8*)&packet, burstSize + 3);
+ pkt1.append(reinterpret_cast<uint8*>(&packet), burstSize + 3);
_session->SendPacket(&pkt1);
}
}
@@ -80,53 +88,49 @@ void Warden::RequestModule()
WardenModuleUse request;
request.Command = WARDEN_SMSG_MODULE_USE;
- memcpy(request.ModuleId, _module->Id, 16);
- memcpy(request.ModuleKey, _module->Key, 16);
+ request.ModuleId = _module->Id;
+ request.ModuleKey = _module->Key;
request.Size = _module->CompressedSize;
+ EndianConvert(request.Size);
+
// Encrypt with warden RC4 key.
- EncryptData((uint8*)&request, sizeof(WardenModuleUse));
+ EncryptData(reinterpret_cast<uint8*>(&request), sizeof(WardenModuleUse));
WorldPacket pkt(SMSG_WARDEN3_DATA, sizeof(WardenModuleUse));
- pkt.append((uint8*)&request, sizeof(WardenModuleUse));
+ pkt.append(reinterpret_cast<uint8*>(&request), sizeof(WardenModuleUse));
_session->SendPacket(&pkt);
}
-void Warden::Update()
+void Warden::Update(uint32 diff)
{
- if (_initialized)
- {
- uint32 currentTimestamp = GameTime::GetGameTimeMS();
- uint32 diff = currentTimestamp - _previousTimestamp;
- _previousTimestamp = currentTimestamp;
+ if (!_initialized)
+ return;
- if (_dataSent)
- {
- uint32 maxClientResponseDelay = sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_RESPONSE_DELAY);
+ if (_dataSent)
+ {
+ uint32 maxClientResponseDelay = sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_RESPONSE_DELAY);
- if (maxClientResponseDelay > 0)
- {
- // Kick player if client response delays more than set in config
- if (_clientResponseTimer > maxClientResponseDelay * IN_MILLISECONDS)
- {
- TC_LOG_WARN("warden", "%s (latency: %u, IP: %s) exceeded Warden module response delay for more than %s - disconnecting client",
- _session->GetPlayerInfo().c_str(), _session->GetLatency(), _session->GetRemoteAddress().c_str(), secsToTimeString(maxClientResponseDelay, TimeFormat::ShortText).c_str());
- _session->KickPlayer("Warden::Update Warden module response delay exceeded");
- }
- else
- _clientResponseTimer += diff;
- }
- }
- else
+ if (maxClientResponseDelay > 0)
{
- if (diff >= _checkTimer)
+ // Kick player if client response delays more than set in config
+ if (_clientResponseTimer > maxClientResponseDelay * IN_MILLISECONDS)
{
- RequestData();
+ TC_LOG_WARN("warden", "%s (latency: %u, IP: %s) exceeded Warden module response delay (%s) - disconnecting client",
+ _session->GetPlayerInfo().c_str(), _session->GetLatency(), _session->GetRemoteAddress().c_str(), secsToTimeString(maxClientResponseDelay, TimeFormat::ShortText).c_str());
+ _session->KickPlayer("Warden::Update Warden module response delay exceeded");
}
else
- _checkTimer -= diff;
+ _clientResponseTimer += diff;
}
}
+ else
+ {
+ if (diff >= _checkTimer)
+ RequestChecks();
+ else
+ _checkTimer -= diff;
+ }
}
void Warden::DecryptData(uint8* buffer, uint32 length)
@@ -181,7 +185,7 @@ uint32 Warden::BuildChecksum(uint8 const* data, uint32 length)
return checkSum;
}
-std::string Warden::Penalty(WardenCheck* check /*= nullptr*/)
+char const* Warden::ApplyPenalty(WardenCheck const* check)
{
WardenActions action;
@@ -192,12 +196,8 @@ std::string Warden::Penalty(WardenCheck* check /*= nullptr*/)
switch (action)
{
- case WARDEN_ACTION_LOG:
- return "None";
- break;
case WARDEN_ACTION_KICK:
_session->KickPlayer("Warden::Penalty");
- return "Kick";
break;
case WARDEN_ACTION_BAN:
{
@@ -208,50 +208,56 @@ std::string Warden::Penalty(WardenCheck* check /*= nullptr*/)
if (check)
banReason += Trinity::StringFormat(": %s (CheckId: %u", check->Comment, uint32(check->CheckId));
- sWorld->BanAccount(BAN_ACCOUNT, accountName, Trinity::StringFormat("%ds", sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_BAN_DURATION)), banReason, "Server");
+ sWorld->BanAccount(BAN_ACCOUNT, accountName, sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_BAN_DURATION), banReason, "Server");
- return "Ban";
+ break;
}
+ case WARDEN_ACTION_LOG:
default:
- break;
+ return "None";
}
- return "Undefined";
+ return EnumUtils::ToTitle(action);
}
-void WorldSession::HandleWardenData(WorldPackets::Warden::WardenData& packet)
+void Warden::HandleData(ByteBuffer& buff)
{
- if (!_warden || packet.Data.empty())
- return;
-
- _warden->DecryptData(packet.Data.contents(), packet.Data.size());
+ DecryptData(buff.contents(), buff.size());
uint8 opcode;
- packet.Data >> opcode;
- TC_LOG_DEBUG("warden", "Got packet, opcode %02X, size %u", opcode, uint32(packet.Data.size()));
- packet.Data.hexlike();
+ buff >> opcode;
+ TC_LOG_DEBUG("warden", "Got packet, opcode %02X, size %u", opcode, uint32(buff.size() - 1));
+ buff.hexlike();
switch (opcode)
{
- case WARDEN_CMSG_MODULE_MISSING:
- _warden->SendModuleToClient();
- break;
- case WARDEN_CMSG_MODULE_OK:
- _warden->RequestHash();
- break;
- case WARDEN_CMSG_CHEAT_CHECKS_RESULT:
- _warden->HandleData(packet.Data);
- break;
- case WARDEN_CMSG_MEM_CHECKS_RESULT:
- TC_LOG_DEBUG("warden", "NYI WARDEN_CMSG_MEM_CHECKS_RESULT received!");
- break;
- case WARDEN_CMSG_HASH_RESULT:
- _warden->HandleHashResult(packet.Data);
- _warden->InitializeModule();
- break;
- case WARDEN_CMSG_MODULE_FAILED:
- TC_LOG_DEBUG("warden", "NYI WARDEN_CMSG_MODULE_FAILED received!");
- break;
- default:
- TC_LOG_DEBUG("warden", "Got unknown warden opcode %02X of size %u.", opcode, uint32(packet.Data.size() - 1));
- break;
+ case WARDEN_CMSG_MODULE_MISSING:
+ SendModuleToClient();
+ break;
+ case WARDEN_CMSG_MODULE_OK:
+ RequestHash();
+ break;
+ case WARDEN_CMSG_CHEAT_CHECKS_RESULT:
+ HandleCheckResult(buff);
+ break;
+ case WARDEN_CMSG_MEM_CHECKS_RESULT:
+ TC_LOG_DEBUG("warden", "NYI WARDEN_CMSG_MEM_CHECKS_RESULT received!");
+ break;
+ case WARDEN_CMSG_HASH_RESULT:
+ HandleHashResult(buff);
+ InitializeModule();
+ break;
+ case WARDEN_CMSG_MODULE_FAILED:
+ TC_LOG_DEBUG("warden", "NYI WARDEN_CMSG_MODULE_FAILED received!");
+ break;
+ default:
+ TC_LOG_WARN("warden", "Got unknown warden opcode %02X of size %u.", opcode, uint32(buff.size() - 1));
+ break;
}
}
+
+void WorldSession::HandleWardenData(WorldPackets::Warden::WardenData& packet)
+{
+ if (!_warden || packet.Data.empty())
+ return;
+
+ _warden->HandleData(packet.Data);
+}
diff --git a/src/server/game/Warden/Warden.h b/src/server/game/Warden/Warden.h
index a5fe29fe889..bcf3cd92122 100644
--- a/src/server/game/Warden/Warden.h
+++ b/src/server/game/Warden/Warden.h
@@ -21,6 +21,7 @@
#include "ARC4.h"
#include "AuthDefines.h"
#include "ByteBuffer.h"
+#include "Optional.h"
#include "WardenCheckMgr.h"
#include <array>
@@ -43,28 +44,16 @@ enum WardenOpcodes
WARDEN_SMSG_HASH_REQUEST = 5
};
-enum WardenCheckType
-{
- MEM_CHECK = 0xF3, // 243: byte moduleNameIndex + uint Offset + byte Len (check to ensure memory isn't modified)
- PAGE_CHECK_A = 0xB2, // 178: uint Seed + byte[20] SHA1 + uint Addr + byte Len (scans all pages for specified hash)
- PAGE_CHECK_B = 0xBF, // 191: uint Seed + byte[20] SHA1 + uint Addr + byte Len (scans only pages starts with MZ+PE headers for specified hash)
- MPQ_CHECK = 0x98, // 152: byte fileNameIndex (check to ensure MPQ file isn't modified)
- LUA_STR_CHECK = 0x8B, // 139: byte luaNameIndex (check to ensure LUA string isn't used)
- DRIVER_CHECK = 0x71, // 113: uint Seed + byte[20] SHA1 + byte driverNameIndex (check to ensure driver isn't loaded)
- TIMING_CHECK = 0x57, // 87: empty (check to ensure GetTickCount() isn't detoured)
- PROC_CHECK = 0x7E, // 126: uint Seed + byte[20] SHA1 + byte moluleNameIndex + byte procNameIndex + uint Offset + byte Len (check to ensure proc isn't detoured)
- MODULE_CHECK = 0xD9 // 217: uint Seed + byte[20] SHA1 (check to ensure module isn't injected)
-};
-
#pragma pack(push, 1)
struct WardenModuleUse
{
uint8 Command;
- uint8 ModuleId[16];
- uint8 ModuleKey[16];
+ std::array<uint8, 16> ModuleId;
+ std::array<uint8, 16> ModuleKey;
uint32 Size;
};
+static_assert(sizeof(WardenModuleUse) == (1 + 16 + 16 + 4));
struct WardenModuleTransfer
{
@@ -72,66 +61,68 @@ struct WardenModuleTransfer
uint16 DataSize;
uint8 Data[500];
};
+static_assert(sizeof(WardenModuleTransfer) == (1 + 2 + 500));
struct WardenHashRequest
{
uint8 Command;
- uint8 Seed[16];
+ std::array<uint8, 16> Seed;
};
+static_assert(sizeof(WardenHashRequest) == (1 + 16));
#pragma pack(pop)
struct ClientWardenModule
{
- uint8 Id[16];
- uint8 Key[16];
- uint32 CompressedSize;
- uint8* CompressedData;
+ std::array<uint8, 16> Id;
+ std::array<uint8, 16> Key;
+ uint8 const* CompressedData;
+ size_t CompressedSize;
};
class WorldSession;
class TC_GAME_API Warden
{
- friend class WardenWin;
- friend class WardenMac;
-
public:
Warden();
virtual ~Warden();
virtual void Init(WorldSession* session, SessionKey const& K) = 0;
- virtual ClientWardenModule* GetModuleForClient() = 0;
+ void Update(uint32 diff);
+ void HandleData(ByteBuffer& buff);
+
+ protected:
+ void DecryptData(uint8* buffer, uint32 length);
+ void EncryptData(uint8* buffer, uint32 length);
+
virtual void InitializeModule() = 0;
virtual void RequestHash() = 0;
- virtual void HandleHashResult(ByteBuffer &buff) = 0;
- virtual void RequestData() = 0;
- virtual void HandleData(ByteBuffer &buff) = 0;
+ virtual void HandleHashResult(ByteBuffer& buff) = 0;
+ virtual void HandleCheckResult(ByteBuffer& buff) = 0;
+ virtual void InitializeModuleForClient(ClientWardenModule& module) = 0;
+ virtual void RequestChecks() = 0;
+ void MakeModuleForClient();
void SendModuleToClient();
void RequestModule();
- void Update();
- void DecryptData(uint8* buffer, uint32 length);
- void EncryptData(uint8* buffer, uint32 length);
static bool IsValidCheckSum(uint32 checksum, const uint8 *data, const uint16 length);
static uint32 BuildChecksum(const uint8 *data, uint32 length);
- // If no check is passed, the default action from config is executed
- std::string Penalty(WardenCheck* check = nullptr);
+ // If nullptr is passed, the default action from config is executed
+ char const* ApplyPenalty(WardenCheck const* check);
- private:
WorldSession* _session;
- uint8 _inputKey[16];
- uint8 _outputKey[16];
- uint8 _seed[16];
+ std::array<uint8, 16> _inputKey = {};
+ std::array<uint8, 16> _outputKey = {};
+ std::array<uint8, 16> _seed = {};
Trinity::Crypto::ARC4 _inputCrypto;
Trinity::Crypto::ARC4 _outputCrypto;
uint32 _checkTimer; // Timer for sending check requests
uint32 _clientResponseTimer; // Timer for client response delay
bool _dataSent;
- uint32 _previousTimestamp;
- ClientWardenModule* _module;
+ Optional<ClientWardenModule> _module;
bool _initialized;
};
diff --git a/src/server/game/Warden/WardenCheckMgr.cpp b/src/server/game/Warden/WardenCheckMgr.cpp
index b23f53f927a..b328eaee6ca 100644
--- a/src/server/game/Warden/WardenCheckMgr.cpp
+++ b/src/server/game/Warden/WardenCheckMgr.cpp
@@ -15,28 +15,21 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "WardenCheckMgr.h"
+
#include "Common.h"
-#include "WorldPacket.h"
-#include "WorldSession.h"
+#include "DatabaseEnv.h"
+#include "Errors.h"
#include "Log.h"
-#include "Database/DatabaseEnv.h"
-#include "WardenCheckMgr.h"
#include "Warden.h"
#include "World.h"
+#include "WorldPacket.h"
+#include "WorldSession.h"
WardenCheckMgr::WardenCheckMgr()
{
}
-WardenCheckMgr::~WardenCheckMgr()
-{
- for (uint16 i = 0; i < CheckStore.size(); ++i)
- delete CheckStore[i];
-
- for (CheckResultContainer::iterator itr = CheckResultStore.begin(); itr != CheckResultStore.end(); ++itr)
- delete itr->second;
-}
-
void WardenCheckMgr::LoadWardenChecks()
{
uint32 oldMSTime = getMSTime();
@@ -70,53 +63,40 @@ void WardenCheckMgr::LoadWardenChecks()
{
fields = result->Fetch();
- uint16 id = fields[0].GetUInt16();
- uint8 checkType = fields[1].GetUInt8();
- std::string data = fields[2].GetString();
- std::string checkResult = fields[3].GetString();
- uint32 address = fields[4].GetUInt32();
- uint8 length = fields[5].GetUInt8();
- std::string str = fields[6].GetString();
- std::string comment = fields[7].GetString();
+ uint16 const id = fields[0].GetUInt16();
+ uint8 const type = fields[1].GetUInt8();
- WardenCheck* wardenCheck = new WardenCheck();
- wardenCheck->Type = checkType;
- wardenCheck->CheckId = id;
+ WardenCheck& wardenCheck = CheckStore[id];
+ wardenCheck.CheckId = id;
+ wardenCheck.Type = WardenCheckType(type);
// Initialize action with default action from config
- wardenCheck->Action = WardenActions(sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_FAIL_ACTION));
+ wardenCheck.Action = WardenActions(sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_FAIL_ACTION));
- if (checkType == PAGE_CHECK_A || checkType == PAGE_CHECK_B || checkType == DRIVER_CHECK)
- wardenCheck->Data.SetHexStr(data.c_str());
+ if (type == PAGE_CHECK_A || type == PAGE_CHECK_B || type == DRIVER_CHECK)
+ wardenCheck.Data = fields[2].GetBinary();
- if (checkType == MEM_CHECK || checkType == MODULE_CHECK)
- MemChecksIdPool.push_back(id);
- else
- OtherChecksIdPool.push_back(id);
+ if (type == MPQ_CHECK || type == MEM_CHECK)
+ CheckResultStore.emplace(id, fields[3].GetBinary());
- if (checkType == MEM_CHECK || checkType == PAGE_CHECK_A || checkType == PAGE_CHECK_B || checkType == PROC_CHECK)
+ if (type == MEM_CHECK || type == PAGE_CHECK_A || type == PAGE_CHECK_B || type == PROC_CHECK)
{
- wardenCheck->Address = address;
- wardenCheck->Length = length;
+ wardenCheck.Address = fields[4].GetUInt32();
+ wardenCheck.Length = fields[5].GetUInt8();
}
// PROC_CHECK support missing
- if (checkType == MEM_CHECK || checkType == MPQ_CHECK || checkType == LUA_STR_CHECK || checkType == DRIVER_CHECK || checkType == MODULE_CHECK)
- wardenCheck->Str = str;
+ if (type == MEM_CHECK || type == MPQ_CHECK || type == LUA_STR_CHECK || type == DRIVER_CHECK || type == MODULE_CHECK)
+ wardenCheck.Str = fields[6].GetString();
- CheckStore[id] = wardenCheck;
-
- if (checkType == MPQ_CHECK || checkType == MEM_CHECK)
- {
- WardenCheckResult* wr = new WardenCheckResult();
- wr->Result.SetHexStr(checkResult.c_str());
- CheckResultStore[id] = wr;
- }
+ wardenCheck.Comment = fields[7].GetString();
+ if (wardenCheck.Comment.empty())
+ wardenCheck.Comment = "Undocumented Check";
- if (comment.empty())
- wardenCheck->Comment = "Undocumented Check";
+ if (type == MEM_CHECK || type == MODULE_CHECK)
+ MemChecksIdPool.push_back(id);
else
- wardenCheck->Comment = comment;
+ OtherChecksIdPool.push_back(id);
++count;
}
@@ -147,8 +127,6 @@ void WardenCheckMgr::LoadWardenOverrides()
uint32 count = 0;
- std::unique_lock<std::shared_mutex> lock(sWardenCheckMgr->_checkStoreLock);
-
do
{
Field* fields = result->Fetch();
@@ -164,7 +142,7 @@ void WardenCheckMgr::LoadWardenOverrides()
TC_LOG_ERROR("warden", "Warden check action override for non-existing check (ID: %u, action: %u), skipped", checkId, action);
else
{
- CheckStore[checkId]->Action = WardenActions(action);
+ CheckStore[checkId].Action = WardenActions(action);
++count;
}
}
@@ -179,18 +157,15 @@ WardenCheckMgr* WardenCheckMgr::instance()
return &instance;
}
-WardenCheck* WardenCheckMgr::GetWardenDataById(uint16 Id)
+WardenCheck const& WardenCheckMgr::GetCheckDataById(uint16 Id) const
{
- if (Id < CheckStore.size())
- return CheckStore[Id];
-
- return nullptr;
+ ASSERT(Id < CheckStore.size(), "Requested Warden data for invalid check ID %u", uint32(Id));
+ return CheckStore[Id];
}
-WardenCheckResult* WardenCheckMgr::GetWardenResultById(uint16 Id)
+WardenCheckResult const& WardenCheckMgr::GetCheckResultById(uint16 Id) const
{
- CheckResultContainer::const_iterator itr = CheckResultStore.find(Id);
- if (itr != CheckResultStore.end())
- return itr->second;
- return nullptr;
+ auto it = CheckResultStore.find(Id);
+ ASSERT(it != CheckResultStore.end(), "Requested Warden result for invalid check ID %u", uint32(Id));
+ return it->second;
}
diff --git a/src/server/game/Warden/WardenCheckMgr.h b/src/server/game/Warden/WardenCheckMgr.h
index 99006aeb3bd..bee75667095 100644
--- a/src/server/game/Warden/WardenCheckMgr.h
+++ b/src/server/game/Warden/WardenCheckMgr.h
@@ -18,61 +18,69 @@
#ifndef _WARDENCHECKMGR_H
#define _WARDENCHECKMGR_H
-#include "Cryptography/BigNumber.h"
-#include <map>
+#include "Define.h"
#include <shared_mutex>
+#include <unordered_map>
+#include <vector>
-enum WardenActions
+// EnumUtils: DESCRIBE THIS
+enum WardenActions : uint8
{
- WARDEN_ACTION_LOG,
- WARDEN_ACTION_KICK,
- WARDEN_ACTION_BAN
+ WARDEN_ACTION_LOG, // TITLE Log
+ WARDEN_ACTION_KICK, // TITLE Kick
+ WARDEN_ACTION_BAN // TITLE Ban
+};
+
+// EnumUtils: DESCRIBE THIS
+enum WardenCheckType : uint8
+{
+ MEM_CHECK = 0xF3, // 243: byte moduleNameIndex + uint Offset + byte Len (check to ensure memory isn't modified)
+ PAGE_CHECK_A = 0xB2, // 178: uint Seed + byte[20] SHA1 + uint Addr + byte Len (scans all pages for specified hash)
+ PAGE_CHECK_B = 0xBF, // 191: uint Seed + byte[20] SHA1 + uint Addr + byte Len (scans only pages starts with MZ+PE headers for specified hash)
+ MPQ_CHECK = 0x98, // 152: byte fileNameIndex (check to ensure MPQ file isn't modified)
+ LUA_STR_CHECK = 0x8B, // 139: byte luaNameIndex (check to ensure LUA string isn't used)
+ DRIVER_CHECK = 0x71, // 113: uint Seed + byte[20] SHA1 + byte driverNameIndex (check to ensure driver isn't loaded)
+ TIMING_CHECK = 0x57, // 87: empty (check to ensure GetTickCount() isn't detoured)
+ PROC_CHECK = 0x7E, // 126: uint Seed + byte[20] SHA1 + byte moluleNameIndex + byte procNameIndex + uint Offset + byte Len (check to ensure proc isn't detoured)
+ MODULE_CHECK = 0xD9 // 217: uint Seed + byte[20] SHA1 (check to ensure module isn't injected)
};
struct WardenCheck
{
- uint8 Type;
- BigNumber Data;
+ WardenCheckType Type;
+ std::vector<uint8> Data;
uint32 Address; // PROC_CHECK, MEM_CHECK, PAGE_CHECK
uint8 Length; // PROC_CHECK, MEM_CHECK, PAGE_CHECK
std::string Str; // LUA, MPQ, DRIVER
std::string Comment;
uint16 CheckId;
- enum WardenActions Action;
+ WardenActions Action;
};
-struct WardenCheckResult
-{
- BigNumber Result; // MEM_CHECK
-};
+using WardenCheckResult = std::vector<uint8>;
class TC_GAME_API WardenCheckMgr
{
private:
WardenCheckMgr();
- ~WardenCheckMgr();
public:
static WardenCheckMgr* instance();
- // We have a linear key without any gaps, so we use vector for fast access
- typedef std::vector<WardenCheck*> CheckContainer;
- typedef std::map<uint32, WardenCheckResult*> CheckResultContainer;
+ WardenCheck const& GetCheckDataById(uint16 Id) const;
+ WardenCheckResult const& GetCheckResultById(uint16 Id) const;
- WardenCheck* GetWardenDataById(uint16 Id);
- WardenCheckResult* GetWardenResultById(uint16 Id);
-
- std::vector<uint16> MemChecksIdPool;
- std::vector<uint16> OtherChecksIdPool;
+ std::vector<uint16> const& GetAvailableMemoryChecks() const { return MemChecksIdPool; }
+ std::vector<uint16> const& GetAvailableOtherChecks() const { return OtherChecksIdPool; }
void LoadWardenChecks();
void LoadWardenOverrides();
- std::shared_mutex _checkStoreLock;
-
private:
- CheckContainer CheckStore;
- CheckResultContainer CheckResultStore;
+ std::vector<WardenCheck> CheckStore;
+ std::unordered_map<uint32, WardenCheckResult> CheckResultStore;
+ std::vector<uint16> MemChecksIdPool;
+ std::vector<uint16> OtherChecksIdPool;
};
#define sWardenCheckMgr WardenCheckMgr::instance()
diff --git a/src/server/game/Warden/WardenMac.cpp b/src/server/game/Warden/WardenMac.cpp
index 56c2942cb65..12293c76b91 100644
--- a/src/server/game/Warden/WardenMac.cpp
+++ b/src/server/game/Warden/WardenMac.cpp
@@ -29,6 +29,7 @@
#include "WorldSession.h"
#include <openssl/md5.h>
+#include <array>
WardenMac::WardenMac() : Warden() { }
@@ -39,8 +40,8 @@ void WardenMac::Init(WorldSession* pClient, SessionKey const& K)
_session = pClient;
// Generate Warden Key
SessionKeyGenerator<Trinity::Crypto::SHA1> WK(K);
- WK.Generate(_inputKey, 16);
- WK.Generate(_outputKey, 16);
+ WK.Generate(_inputKey.data(), 16);
+ WK.Generate(_outputKey.data(), 16);
/*
Seed: 4D808D2C77D905C41A6380EC08586AFE (0x05 packet)
Hash: <?> (0x04 packet)
@@ -48,9 +49,8 @@ void WardenMac::Init(WorldSession* pClient, SessionKey const& K)
New Client Key: <?>
New Cerver Key: <?>
*/
- uint8 mod_seed[16] = { 0x4D, 0x80, 0x8D, 0x2C, 0x77, 0xD9, 0x05, 0xC4, 0x1A, 0x63, 0x80, 0xEC, 0x08, 0x58, 0x6A, 0xFE };
- memcpy(_seed, mod_seed, 16);
+ _seed = { 0x4D, 0x80, 0x8D, 0x2C, 0x77, 0xD9, 0x05, 0xC4, 0x1A, 0x63, 0x80, 0xEC, 0x08, 0x58, 0x6A, 0xFE };
_inputCrypto.Init(_inputKey);
_outputCrypto.Init(_outputKey);
@@ -60,32 +60,18 @@ void WardenMac::Init(WorldSession* pClient, SessionKey const& K)
TC_LOG_DEBUG("warden", " Seed: %s", ByteArrayToHexStr(_seed).c_str());
TC_LOG_DEBUG("warden", "Loading Module...");
- _module = GetModuleForClient();
+ MakeModuleForClient();
TC_LOG_DEBUG("warden", "Module Key: %s", ByteArrayToHexStr(_module->Key).c_str());
TC_LOG_DEBUG("warden", "Module ID: %s", ByteArrayToHexStr(_module->Id).c_str());
RequestModule();
}
-ClientWardenModule* WardenMac::GetModuleForClient()
+void WardenMac::InitializeModuleForClient(ClientWardenModule& module)
{
- ClientWardenModule *mod = new ClientWardenModule;
-
- uint32 len = sizeof(Module_0DBBF209A27B1E279A9FEC5C168A15F7_Data);
-
// data assign
- mod->CompressedSize = len;
- mod->CompressedData = new uint8[len];
- memcpy(mod->CompressedData, Module_0DBBF209A27B1E279A9FEC5C168A15F7_Data, len);
- memcpy(mod->Key, Module_0DBBF209A27B1E279A9FEC5C168A15F7_Key, 16);
-
- // md5 hash
- MD5_CTX ctx;
- MD5_Init(&ctx);
- MD5_Update(&ctx, mod->CompressedData, len);
- MD5_Final((uint8*)&mod->Id, &ctx);
-
- return mod;
+ module.CompressedData = Module_0DBBF209A27B1E279A9FEC5C168A15F7_Data.data();
+ module.CompressedSize = Module_0DBBF209A27B1E279A9FEC5C168A15F7_Data.size();
}
void WardenMac::InitializeModule()
@@ -100,7 +86,7 @@ void WardenMac::RequestHash()
// Create packet structure
WardenHashRequest Request;
Request.Command = WARDEN_SMSG_HASH_REQUEST;
- memcpy(Request.Seed, _seed, 16);
+ Request.Seed = _seed;
// Encrypt with warden RC4 key.
EncryptData((uint8*)&Request, sizeof(WardenHashRequest));
@@ -152,18 +138,15 @@ void WardenMac::HandleHashResult(ByteBuffer &buff)
keyOut[3] = 0x1337F00D * keyIn[3];
// end test
- buff.rpos(buff.wpos());
-
- Trinity::Crypto::SHA1 sha1;
- sha1.UpdateData((uint8*)keyIn, 16);
- sha1.Finalize();
-
//const uint8 validHash[20] = { 0x56, 0x8C, 0x05, 0x4C, 0x78, 0x1A, 0x97, 0x2A, 0x60, 0x37, 0xA2, 0x29, 0x0C, 0x22, 0xB5, 0x25, 0x71, 0xA0, 0x6F, 0x4E };
// Verify key
- if (memcmp(buff.contents() + 1, sha1.GetDigest().data(), 20) != 0)
+ Trinity::Crypto::SHA1::Digest result;
+ buff.read(result);
+ if (result != Trinity::Crypto::SHA1::GetDigestOf(reinterpret_cast<uint8*>(keyIn), 16))
{
- TC_LOG_WARN("warden", "%s failed hash reply. Action: %s", _session->GetPlayerInfo().c_str(), Penalty().c_str());
+ char const* penalty = ApplyPenalty(nullptr);
+ TC_LOG_WARN("warden", "%s failed hash reply. Action: %s", _session->GetPlayerInfo().c_str(), penalty);
return;
}
@@ -176,18 +159,16 @@ void WardenMac::HandleHashResult(ByteBuffer &buff)
//const uint8 server_key[16] = { 0xC2, 0xB7, 0xAD, 0xED, 0xFC, 0xCC, 0xA9, 0xC2, 0xBF, 0xB3, 0xF8, 0x56, 0x02, 0xBA, 0x80, 0x9B };
// change keys here
- memcpy(_inputKey, keyIn, 16);
- memcpy(_outputKey, keyOut, 16);
+ memcpy(_inputKey.data(), keyIn, 16);
+ memcpy(_outputKey.data(), keyOut, 16);
_inputCrypto.Init(_inputKey);
_outputCrypto.Init(_outputKey);
_initialized = true;
-
- _previousTimestamp = GameTime::GetGameTimeMS();
}
-void WardenMac::RequestData()
+void WardenMac::RequestChecks()
{
TC_LOG_DEBUG("warden", "Request data");
@@ -211,7 +192,7 @@ void WardenMac::RequestData()
_dataSent = true;
}
-void WardenMac::HandleData(ByteBuffer &buff)
+void WardenMac::HandleCheckResult(ByteBuffer &buff)
{
TC_LOG_DEBUG("warden", "Handle data");
@@ -253,17 +234,17 @@ void WardenMac::HandleData(ByteBuffer &buff)
MD5_CTX ctx;
MD5_Init(&ctx);
MD5_Update(&ctx, str.c_str(), str.size());
- uint8 ourMD5Hash[16];
- MD5_Final(ourMD5Hash, &ctx);
+ std::array<uint8, 16> ourMD5Hash;
+ MD5_Final(ourMD5Hash.data(), &ctx);
- uint8 theirsMD5Hash[16];
- buff.read(theirsMD5Hash, 16);
+ std::array<uint8, 16> theirsMD5Hash;
+ buff.read(theirsMD5Hash);
- if (memcmp(ourMD5Hash, theirsMD5Hash, 16) != 0)
+ if (ourMD5Hash != theirsMD5Hash)
{
TC_LOG_DEBUG("warden", "Handle data failed: MD5 hash is wrong!");
//found = true;
}
- _session->KickPlayer("WardenMac::HandleData");
+ _session->KickPlayer("WardenMac::HandleCheckResult");
}
diff --git a/src/server/game/Warden/WardenMac.h b/src/server/game/Warden/WardenMac.h
index 18cf5c09fe6..d9fbf2a9870 100644
--- a/src/server/game/Warden/WardenMac.h
+++ b/src/server/game/Warden/WardenMac.h
@@ -32,12 +32,12 @@ class TC_GAME_API WardenMac : public Warden
~WardenMac();
void Init(WorldSession* session, SessionKey const& k) override;
- ClientWardenModule* GetModuleForClient() override;
+ void InitializeModuleForClient(ClientWardenModule& module) override;
void InitializeModule() override;
void RequestHash() override;
void HandleHashResult(ByteBuffer& buff) override;
- void RequestData() override;
- void HandleData(ByteBuffer& buff) override;
+ void RequestChecks() override;
+ void HandleCheckResult(ByteBuffer& buff) override;
};
#endif
diff --git a/src/server/game/Warden/WardenWin.cpp b/src/server/game/Warden/WardenWin.cpp
index 42b718723a0..1118eb1113c 100644
--- a/src/server/game/Warden/WardenWin.cpp
+++ b/src/server/game/Warden/WardenWin.cpp
@@ -18,6 +18,7 @@
#include "WardenWin.h"
#include "Common.h"
#include "ByteBuffer.h"
+#include "Containers.h"
#include "CryptoRandom.h"
#include "DatabaseEnv.h"
#include "GameTime.h"
@@ -27,28 +28,35 @@
#include "Player.h"
#include "Random.h"
#include "SessionKeyGenerator.h"
+#include "SmartEnum.h"
#include "Util.h"
#include "WardenModuleWin.h"
#include "WardenCheckMgr.h"
#include "World.h"
#include "WorldPacket.h"
#include "WorldSession.h"
-#include <openssl/md5.h>
#include <sstream>
-WardenWin::WardenWin() : Warden(), _serverTicks(0) {}
+WardenWin::WardenWin() : Warden(), _serverTicks(0)
+{
+ _memChecks = sWardenCheckMgr->GetAvailableMemoryChecks();
+ Trinity::Containers::RandomShuffle(_memChecks);
+ _memChecksIt = _memChecks.begin();
-WardenWin::~WardenWin() { }
+ _otherChecks = sWardenCheckMgr->GetAvailableOtherChecks();
+ Trinity::Containers::RandomShuffle(_otherChecks);
+ _otherChecksIt = _otherChecks.begin();
+}
void WardenWin::Init(WorldSession* session, SessionKey const& K)
{
_session = session;
// Generate Warden Key
SessionKeyGenerator<Trinity::Crypto::SHA1> WK(K);
- WK.Generate(_inputKey, 16);
- WK.Generate(_outputKey, 16);
+ WK.Generate(_inputKey.data(), _inputKey.size());
+ WK.Generate(_outputKey.data(), _outputKey.size());
- memcpy(_seed, Module.Seed, 16);
+ _seed = Module.Seed;
_inputCrypto.Init(_inputKey);
_outputCrypto.Init(_outputKey);
@@ -58,32 +66,19 @@ void WardenWin::Init(WorldSession* session, SessionKey const& K)
TC_LOG_DEBUG("warden", " Seed: %s", ByteArrayToHexStr(_seed).c_str());
TC_LOG_DEBUG("warden", "Loading Module...");
- _module = GetModuleForClient();
+ MakeModuleForClient();
TC_LOG_DEBUG("warden", "Module Key: %s", ByteArrayToHexStr(_module->Key).c_str());
TC_LOG_DEBUG("warden", "Module ID: %s", ByteArrayToHexStr(_module->Id).c_str());
RequestModule();
}
-ClientWardenModule* WardenWin::GetModuleForClient()
+void WardenWin::InitializeModuleForClient(ClientWardenModule& module)
{
- ClientWardenModule *mod = new ClientWardenModule;
-
- uint32 length = sizeof(Module.Module);
-
// data assign
- mod->CompressedSize = length;
- mod->CompressedData = new uint8[length];
- memcpy(mod->CompressedData, Module.Module, length);
- memcpy(mod->Key, Module.ModuleKey, 16);
-
- // md5 hash
- MD5_CTX ctx;
- MD5_Init(&ctx);
- MD5_Update(&ctx, mod->CompressedData, length);
- MD5_Final((uint8*)&mod->Id, &ctx);
-
- return mod;
+ module.CompressedData = Module.Module.data();
+ module.CompressedSize = Module.Module.size();
+ module.Key = Module.ModuleKey;
}
void WardenWin::InitializeModule()
@@ -122,11 +117,24 @@ void WardenWin::InitializeModule()
Request.Function3_set = 1;
Request.CheckSumm3 = BuildChecksum(&Request.Unk5, 8);
+ EndianConvert(Request.Size1);
+ EndianConvert(Request.CheckSumm1);
+ EndianConvert(Request.Function1[0]);
+ EndianConvert(Request.Function1[1]);
+ EndianConvert(Request.Function1[2]);
+ EndianConvert(Request.Function1[3]);
+ EndianConvert(Request.Size2);
+ EndianConvert(Request.CheckSumm2);
+ EndianConvert(Request.Function2);
+ EndianConvert(Request.Size3);
+ EndianConvert(Request.CheckSumm3);
+ EndianConvert(Request.Function3);
+
// Encrypt with warden RC4 key.
- EncryptData((uint8*)&Request, sizeof(WardenInitModuleRequest));
+ EncryptData(reinterpret_cast<uint8*>(&Request), sizeof(WardenInitModuleRequest));
WorldPacket pkt(SMSG_WARDEN3_DATA, sizeof(WardenInitModuleRequest));
- pkt.append((uint8*)&Request, sizeof(WardenInitModuleRequest));
+ pkt.append(reinterpret_cast<uint8*>(&Request), sizeof(WardenInitModuleRequest));
_session->SendPacket(&pkt);
}
@@ -137,105 +145,91 @@ void WardenWin::RequestHash()
// Create packet structure
WardenHashRequest Request;
Request.Command = WARDEN_SMSG_HASH_REQUEST;
- memcpy(Request.Seed, _seed, 16);
+ Request.Seed = _seed;
// Encrypt with warden RC4 key.
- EncryptData((uint8*)&Request, sizeof(WardenHashRequest));
+ EncryptData(reinterpret_cast<uint8*>(&Request), sizeof(WardenHashRequest));
WorldPacket pkt(SMSG_WARDEN3_DATA, sizeof(WardenHashRequest));
- pkt.append((uint8*)&Request, sizeof(WardenHashRequest));
+ pkt.append(reinterpret_cast<uint8*>(&Request), sizeof(WardenHashRequest));
_session->SendPacket(&pkt);
}
void WardenWin::HandleHashResult(ByteBuffer &buff)
{
- buff.rpos(buff.wpos());
-
// Verify key
- if (memcmp(buff.contents() + 1, Module.ClientKeySeedHash, 20) != 0)
+ Trinity::Crypto::SHA1::Digest response;
+ buff.read(response);
+ if (response != Module.ClientKeySeedHash)
{
- TC_LOG_WARN("warden", "%s failed hash reply. Action: %s", _session->GetPlayerInfo().c_str(), Penalty().c_str());
+ char const* penalty = ApplyPenalty(nullptr);
+ TC_LOG_WARN("warden", "%s failed hash reply. Action: %s", _session->GetPlayerInfo().c_str(), penalty);
return;
}
TC_LOG_DEBUG("warden", "Request hash reply: succeed");
// Change keys here
- memcpy(_inputKey, Module.ClientKeySeed, 16);
- memcpy(_outputKey, Module.ServerKeySeed, 16);
+ _inputKey = Module.ClientKeySeed;
+ _outputKey = Module.ServerKeySeed;
_inputCrypto.Init(_inputKey);
_outputCrypto.Init(_outputKey);
_initialized = true;
-
- _previousTimestamp = GameTime::GetGameTimeMS();
}
-void WardenWin::RequestData()
+void WardenWin::RequestChecks()
{
TC_LOG_DEBUG("warden", "Request data");
// If all checks were done, fill the todo list again
- if (_memChecksTodo.empty())
- _memChecksTodo.assign(sWardenCheckMgr->MemChecksIdPool.begin(), sWardenCheckMgr->MemChecksIdPool.end());
+ if (_memChecksIt == _memChecks.end())
+ {
+ TC_LOG_DEBUG("warden", "Finished all mem checks, re-shuffling");
+ Trinity::Containers::RandomShuffle(_memChecks);
+ _memChecksIt = _memChecks.begin();
+ }
- if (_otherChecksTodo.empty())
- _otherChecksTodo.assign(sWardenCheckMgr->OtherChecksIdPool.begin(), sWardenCheckMgr->OtherChecksIdPool.end());
+ if (_otherChecksIt == _otherChecks.end())
+ {
+ TC_LOG_DEBUG("warden", "Finished all other checks, re-shuffling");
+ Trinity::Containers::RandomShuffle(_otherChecks);
+ _otherChecksIt = _otherChecks.begin();
+ }
_serverTicks = GameTime::GetGameTimeMS();
- uint16 id;
- uint8 type;
- WardenCheck* wd;
_currentChecks.clear();
// Build check request
+ ByteBuffer buff;
+ buff << uint8(WARDEN_SMSG_CHEAT_CHECKS_REQUEST);
+
for (uint32 i = 0; i < sWorld->getIntConfig(CONFIG_WARDEN_NUM_MEM_CHECKS); ++i)
{
// If todo list is done break loop (will be filled on next Update() run)
- if (_memChecksTodo.empty())
+ if (_memChecksIt == _memChecks.end())
break;
- // Get check id from the end and remove it from todo
- id = _memChecksTodo.back();
- _memChecksTodo.pop_back();
-
- // Add the id to the list sent in this cycle
- _currentChecks.push_back(id);
+ _currentChecks.push_back(*(_memChecksIt++));
}
- ByteBuffer buff;
- buff << uint8(WARDEN_SMSG_CHEAT_CHECKS_REQUEST);
-
- std::shared_lock<std::shared_mutex> lock(sWardenCheckMgr->_checkStoreLock);
-
for (uint32 i = 0; i < sWorld->getIntConfig(CONFIG_WARDEN_NUM_OTHER_CHECKS); ++i)
{
// If todo list is done break loop (will be filled on next Update() run)
- if (_otherChecksTodo.empty())
+ if (_otherChecksIt == _otherChecks.end())
break;
- // Get check id from the end and remove it from todo
- id = _otherChecksTodo.back();
- _otherChecksTodo.pop_back();
-
- // Add the id to the list sent in this cycle
- _currentChecks.push_back(id);
+ uint16 const id = *(_otherChecksIt++);
- wd = sWardenCheckMgr->GetWardenDataById(id);
-
- switch (wd->Type)
+ WardenCheck const& check = sWardenCheckMgr->GetCheckDataById(id);
+ if (!check.Str.empty())
{
- case MPQ_CHECK:
- case LUA_STR_CHECK:
- case DRIVER_CHECK:
- buff << uint8(wd->Str.size());
- buff.append(wd->Str.c_str(), wd->Str.size());
- break;
- default:
- break;
+ buff << uint8(check.Str.size());
+ buff.append(check.Str.data(), check.Str.size());
}
+ _currentChecks.push_back(id);
}
uint8 xorByte = _inputKey[0];
@@ -246,28 +240,27 @@ void WardenWin::RequestData()
uint8 index = 1;
- for (std::list<uint16>::iterator itr = _currentChecks.begin(); itr != _currentChecks.end(); ++itr)
+ for (uint16 const id : _currentChecks)
{
- wd = sWardenCheckMgr->GetWardenDataById(*itr);
+ WardenCheck const& check = sWardenCheckMgr->GetCheckDataById(id);
- type = wd->Type;
+ WardenCheckType const type = check.Type;
buff << uint8(type ^ xorByte);
switch (type)
{
case MEM_CHECK:
{
buff << uint8(0x00);
- buff << uint32(wd->Address);
- buff << uint8(wd->Length);
+ buff << uint32(check.Address);
+ buff << uint8(check.Length);
break;
}
case PAGE_CHECK_A:
case PAGE_CHECK_B:
{
- std::vector<uint8> data = wd->Data.ToByteVector(0, false);
- buff.append(data.data(), data.size());
- buff << uint32(wd->Address);
- buff << uint8(wd->Length);
+ buff.append(check.Data.data(), check.Data.size());
+ buff << uint32(check.Address);
+ buff << uint8(check.Length);
break;
}
case MPQ_CHECK:
@@ -278,8 +271,7 @@ void WardenWin::RequestData()
}
case DRIVER_CHECK:
{
- std::vector<uint8> data = wd->Data.ToByteVector(0, false);
- buff.append(data.data(), data.size());
+ buff.append(check.Data.data(), check.Data.size());
buff << uint8(index++);
break;
}
@@ -287,16 +279,16 @@ void WardenWin::RequestData()
{
std::array<uint8, 4> seed = Trinity::Crypto::GetRandomBytes<4>();
buff.append(seed);
- buff.append(Trinity::Crypto::HMAC_SHA1::GetDigestOf(seed, wd->Str));
+ buff.append(Trinity::Crypto::HMAC_SHA1::GetDigestOf(seed, check.Str));
break;
}
/*case PROC_CHECK:
{
- buff.append(wd->i.AsByteArray(0, false).get(), wd->i.GetNumBytes());
+ buff.append(check->i.AsByteArray(0, false).get(), check->i.GetNumBytes());
buff << uint8(index++);
buff << uint8(index++);
- buff << uint32(wd->Address);
- buff << uint8(wd->Length);
+ buff << uint32(check->Address);
+ buff << uint8(check->Length);
break;
}*/
default:
@@ -317,13 +309,13 @@ void WardenWin::RequestData()
std::stringstream stream;
stream << "Sent check id's: ";
- for (std::list<uint16>::iterator itr = _currentChecks.begin(); itr != _currentChecks.end(); ++itr)
- stream << *itr << " ";
+ for (uint16 const id : _currentChecks)
+ stream << id << " ";
TC_LOG_DEBUG("warden", "%s", stream.str().c_str());
}
-void WardenWin::HandleData(ByteBuffer &buff)
+void WardenWin::HandleCheckResult(ByteBuffer &buff)
{
TC_LOG_DEBUG("warden", "Handle data");
@@ -335,10 +327,19 @@ void WardenWin::HandleData(ByteBuffer &buff)
uint32 Checksum;
buff >> Checksum;
+ if (Length != (buff.size() - buff.rpos()))
+ {
+ buff.rfinish();
+ char const* penalty = ApplyPenalty(nullptr);
+ TC_LOG_WARN("warden", "%s sends manipulated warden packet. Action: %s", _session->GetPlayerInfo().c_str(), penalty);
+ return;
+ }
+
if (!IsValidCheckSum(Checksum, buff.contents() + buff.rpos(), Length))
{
- buff.rpos(buff.wpos());
- TC_LOG_WARN("warden", "%s failed checksum. Action: %s", _session->GetPlayerInfo().c_str(), Penalty().c_str());
+ buff.rfinish();
+ char const* penalty = ApplyPenalty(nullptr);
+ TC_LOG_WARN("warden", "%s failed checksum. Action: %s", _session->GetPlayerInfo().c_str(), penalty);
return;
}
@@ -349,7 +350,8 @@ void WardenWin::HandleData(ByteBuffer &buff)
/// @todo test it.
if (result == 0x00)
{
- TC_LOG_WARN("warden", "%s failed timing check. Action: %s", _session->GetPlayerInfo().c_str(), Penalty().c_str());
+ char const* penalty = ApplyPenalty(nullptr);
+ TC_LOG_WARN("warden", "%s failed timing check. Action: %s", _session->GetPlayerInfo().c_str(), penalty);
return;
}
@@ -359,26 +361,18 @@ void WardenWin::HandleData(ByteBuffer &buff)
uint32 ticksNow = GameTime::GetGameTimeMS();
uint32 ourTicks = newClientTicks + (ticksNow - _serverTicks);
- TC_LOG_DEBUG("warden", "ServerTicks %u", ticksNow); // Now
- TC_LOG_DEBUG("warden", "RequestTicks %u", _serverTicks); // At request
- TC_LOG_DEBUG("warden", "Ticks %u", newClientTicks); // At response
- TC_LOG_DEBUG("warden", "Ticks diff %u", ourTicks - newClientTicks);
+ TC_LOG_DEBUG("warden", "Server tick count now: %u", ticksNow);
+ TC_LOG_DEBUG("warden", "Server tick count at req: %u", _serverTicks);
+ TC_LOG_DEBUG("warden", "Client ticks in response: %u", newClientTicks);
+ TC_LOG_DEBUG("warden", "Round trip response time: %u ms", ourTicks - newClientTicks);
}
- WardenCheckResult* rs;
- WardenCheck *rd;
- uint8 type;
uint16 checkFailed = 0;
-
- std::shared_lock<std::shared_mutex> lock(sWardenCheckMgr->_checkStoreLock);
-
- for (std::list<uint16>::iterator itr = _currentChecks.begin(); itr != _currentChecks.end(); ++itr)
+ for (uint16 const id : _currentChecks)
{
- rd = sWardenCheckMgr->GetWardenDataById(*itr);
- rs = sWardenCheckMgr->GetWardenResultById(*itr);
+ WardenCheck const& check = sWardenCheckMgr->GetCheckDataById(id);
- type = rd->Type;
- switch (type)
+ switch (check.Type)
{
case MEM_CHECK:
{
@@ -387,22 +381,22 @@ void WardenWin::HandleData(ByteBuffer &buff)
if (Mem_Result != 0)
{
- TC_LOG_DEBUG("warden", "RESULT MEM_CHECK not 0x00, CheckId %u account Id %u", *itr, _session->GetAccountId());
- checkFailed = *itr;
+ TC_LOG_DEBUG("warden", "RESULT MEM_CHECK not 0x00, CheckId %u account Id %u", id, _session->GetAccountId());
+ checkFailed = id;
continue;
}
- std::vector<uint8> result = rs->Result.ToByteVector(0, false);
- if (memcmp(buff.contents() + buff.rpos(), result.data(), rd->Length) != 0)
+ std::vector<uint8> response;
+ response.resize(check.Length);
+ buff.read(response.data(), response.size());
+ if (response != sWardenCheckMgr->GetCheckResultById(id))
{
- TC_LOG_DEBUG("warden", "RESULT MEM_CHECK fail CheckId %u account Id %u", *itr, _session->GetAccountId());
- checkFailed = *itr;
- buff.rpos(buff.rpos() + rd->Length);
+ TC_LOG_DEBUG("warden", "RESULT MEM_CHECK fail CheckId %u account Id %u", id, _session->GetAccountId());
+ checkFailed = id;
continue;
}
- buff.rpos(buff.rpos() + rd->Length);
- TC_LOG_DEBUG("warden", "RESULT MEM_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId());
+ TC_LOG_DEBUG("warden", "RESULT MEM_CHECK passed CheckId %u account Id %u", id, _session->GetAccountId());
break;
}
case PAGE_CHECK_A:
@@ -410,27 +404,14 @@ void WardenWin::HandleData(ByteBuffer &buff)
case DRIVER_CHECK:
case MODULE_CHECK:
{
- const uint8 byte = 0xE9;
- if (memcmp(buff.contents() + buff.rpos(), &byte, sizeof(uint8)) != 0)
+ if (buff.read<uint8>() != 0xE9)
{
- if (type == PAGE_CHECK_A || type == PAGE_CHECK_B)
- TC_LOG_DEBUG("warden", "RESULT PAGE_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId());
- if (type == MODULE_CHECK)
- TC_LOG_DEBUG("warden", "RESULT MODULE_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId());
- if (type == DRIVER_CHECK)
- TC_LOG_DEBUG("warden", "RESULT DRIVER_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId());
- checkFailed = *itr;
- buff.rpos(buff.rpos() + 1);
+ TC_LOG_DEBUG("warden", "RESULT %s fail, CheckId %u account Id %u", EnumUtils::ToConstant(check.Type), id, _session->GetAccountId());
+ checkFailed = id;
continue;
}
- buff.rpos(buff.rpos() + 1);
- if (type == PAGE_CHECK_A || type == PAGE_CHECK_B)
- TC_LOG_DEBUG("warden", "RESULT PAGE_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId());
- else if (type == MODULE_CHECK)
- TC_LOG_DEBUG("warden", "RESULT MODULE_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId());
- else if (type == DRIVER_CHECK)
- TC_LOG_DEBUG("warden", "RESULT DRIVER_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId());
+ TC_LOG_DEBUG("warden", "RESULT %s passed CheckId %u account Id %u", EnumUtils::ToConstant(check.Type), id, _session->GetAccountId());
break;
}
case LUA_STR_CHECK:
@@ -440,24 +421,20 @@ void WardenWin::HandleData(ByteBuffer &buff)
if (Lua_Result != 0)
{
- TC_LOG_DEBUG("warden", "RESULT LUA_STR_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId());
- checkFailed = *itr;
+ TC_LOG_DEBUG("warden", "RESULT LUA_STR_CHECK fail, CheckId %u account Id %u", id, _session->GetAccountId());
+ checkFailed = id;
continue;
}
- uint8 luaStrLen;
- buff >> luaStrLen;
-
+ uint8 luaStrLen = buff.read<uint8>();
if (luaStrLen != 0)
{
- char *str = new char[luaStrLen + 1];
- memcpy(str, buff.contents() + buff.rpos(), luaStrLen);
- str[luaStrLen] = '\0'; // null terminator
- TC_LOG_DEBUG("warden", "Lua string: %s", str);
- delete[] str;
+ std::string str;
+ str.resize(luaStrLen);
+ buff.read(reinterpret_cast<uint8*>(str.data()), luaStrLen);
+ TC_LOG_DEBUG("warden", "Lua string: %s", str.c_str());
}
- buff.rpos(buff.rpos() + luaStrLen); // Skip string
- TC_LOG_DEBUG("warden", "RESULT LUA_STR_CHECK passed, CheckId %u account Id %u", *itr, _session->GetAccountId());
+ TC_LOG_DEBUG("warden", "RESULT LUA_STR_CHECK passed, CheckId %u account Id %u", id, _session->GetAccountId());
break;
}
case MPQ_CHECK:
@@ -468,20 +445,21 @@ void WardenWin::HandleData(ByteBuffer &buff)
if (Mpq_Result != 0)
{
TC_LOG_DEBUG("warden", "RESULT MPQ_CHECK not 0x00 account id %u", _session->GetAccountId());
- checkFailed = *itr;
+ checkFailed = id;
continue;
}
- if (memcmp(buff.contents() + buff.rpos(), rs->Result.ToByteArray<20>(false).data(), 20) != 0) // SHA1
+ std::vector<uint8> result;
+ result.resize(Trinity::Crypto::SHA1::DIGEST_LENGTH);
+ buff.read(result.data(), result.size());
+ if (result != sWardenCheckMgr->GetCheckResultById(id)) // SHA1
{
- TC_LOG_DEBUG("warden", "RESULT MPQ_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId());
- checkFailed = *itr;
- buff.rpos(buff.rpos() + 20); // 20 bytes SHA1
+ TC_LOG_DEBUG("warden", "RESULT MPQ_CHECK fail, CheckId %u account Id %u", id, _session->GetAccountId());
+ checkFailed = id;
continue;
}
- buff.rpos(buff.rpos() + 20); // 20 bytes SHA1
- TC_LOG_DEBUG("warden", "RESULT MPQ_CHECK passed, CheckId %u account Id %u", *itr, _session->GetAccountId());
+ TC_LOG_DEBUG("warden", "RESULT MPQ_CHECK passed, CheckId %u account Id %u", id, _session->GetAccountId());
break;
}
default: // Should never happen
@@ -491,8 +469,9 @@ void WardenWin::HandleData(ByteBuffer &buff)
if (checkFailed > 0)
{
- WardenCheck* check = sWardenCheckMgr->GetWardenDataById(checkFailed);
- TC_LOG_WARN("warden", "%s failed Warden check %u. Action: %s", _session->GetPlayerInfo().c_str(), checkFailed, Penalty(check).c_str());
+ WardenCheck const& check = sWardenCheckMgr->GetCheckDataById(checkFailed);
+ char const* penalty = ApplyPenalty(&check);
+ TC_LOG_WARN("warden", "%s failed Warden check %u (%s). Action: %s", _session->GetPlayerInfo().c_str(), checkFailed, EnumUtils::ToConstant(check.Type), penalty);
}
// Set hold off timer, minimum timer should at least be 1 second
diff --git a/src/server/game/Warden/WardenWin.h b/src/server/game/Warden/WardenWin.h
index ff4093738df..e8bcbd56e9f 100644
--- a/src/server/game/Warden/WardenWin.h
+++ b/src/server/game/Warden/WardenWin.h
@@ -55,6 +55,7 @@ struct WardenInitModuleRequest
uint32 Function3;
uint8 Function3_set;
};
+static_assert(sizeof(WardenInitModuleRequest) == (1 + 2 + 4 + 1 + 1 + 1 + 1 + (4 * 4) + 1 + 2 + 4 + 1 + 1 + 1 + 4 + 1 + 1 + 2 + 4 + 1 + 1 + 1 + 4 + 1));
#pragma pack(pop)
@@ -65,21 +66,22 @@ class TC_GAME_API WardenWin : public Warden
{
public:
WardenWin();
- ~WardenWin();
void Init(WorldSession* session, SessionKey const& K) override;
- ClientWardenModule* GetModuleForClient() override;
+ void InitializeModuleForClient(ClientWardenModule& module) override;
void InitializeModule() override;
void RequestHash() override;
void HandleHashResult(ByteBuffer &buff) override;
- void RequestData() override;
- void HandleData(ByteBuffer &buff) override;
+ void RequestChecks() override;
+ void HandleCheckResult(ByteBuffer &buff) override;
private:
uint32 _serverTicks;
- std::list<uint16> _otherChecksTodo;
- std::list<uint16> _memChecksTodo;
- std::list<uint16> _currentChecks;
+ std::vector<uint16> _memChecks;
+ std::vector<uint16>::const_iterator _memChecksIt;
+ std::vector<uint16> _otherChecks;
+ std::vector<uint16>::const_iterator _otherChecksIt;
+ std::vector<uint16> _currentChecks;
};
#endif
diff --git a/src/server/game/Warden/enuminfo_WardenCheckMgr.cpp b/src/server/game/Warden/enuminfo_WardenCheckMgr.cpp
new file mode 100644
index 00000000000..e4c5fc4efa3
--- /dev/null
+++ b/src/server/game/Warden/enuminfo_WardenCheckMgr.cpp
@@ -0,0 +1,100 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "WardenCheckMgr.h"
+#include "Define.h"
+#include "SmartEnum.h"
+#include <stdexcept>
+
+namespace Trinity
+{
+namespace Impl
+{
+
+/**********************************************************************\
+|* data for enum 'WardenActions' in 'WardenCheckMgr.h' auto-generated *|
+\**********************************************************************/
+template <>
+TC_API_EXPORT EnumText EnumUtils<WardenActions>::ToString(WardenActions value)
+{
+ switch (value)
+ {
+ case WARDEN_ACTION_LOG: return { "WARDEN_ACTION_LOG", "Log", "" };
+ case WARDEN_ACTION_KICK: return { "WARDEN_ACTION_KICK", "Kick", "" };
+ case WARDEN_ACTION_BAN: return { "WARDEN_ACTION_BAN", "Ban", "" };
+ default: throw std::out_of_range("value");
+ }
+}
+
+template <>
+TC_API_EXPORT size_t EnumUtils<WardenActions>::Count() { return 3; }
+
+template <>
+TC_API_EXPORT WardenActions EnumUtils<WardenActions>::FromIndex(size_t index)
+{
+ switch (index)
+ {
+ case 0: return WARDEN_ACTION_LOG;
+ case 1: return WARDEN_ACTION_KICK;
+ case 2: return WARDEN_ACTION_BAN;
+ default: throw std::out_of_range("index");
+ }
+}
+
+/************************************************************************\
+|* data for enum 'WardenCheckType' in 'WardenCheckMgr.h' auto-generated *|
+\************************************************************************/
+template <>
+TC_API_EXPORT EnumText EnumUtils<WardenCheckType>::ToString(WardenCheckType value)
+{
+ switch (value)
+ {
+ case MEM_CHECK: return { "MEM_CHECK", "MEM_CHECK", "243: byte moduleNameIndex + uint Offset + byte Len (check to ensure memory isn't modified)" };
+ case PAGE_CHECK_A: return { "PAGE_CHECK_A", "PAGE_CHECK_A", "178: uint Seed + byte[20] SHA1 + uint Addr + byte Len (scans all pages for specified hash)" };
+ case PAGE_CHECK_B: return { "PAGE_CHECK_B", "PAGE_CHECK_B", "191: uint Seed + byte[20] SHA1 + uint Addr + byte Len (scans only pages starts with MZ+PE headers for specified hash)" };
+ case MPQ_CHECK: return { "MPQ_CHECK", "MPQ_CHECK", "152: byte fileNameIndex (check to ensure MPQ file isn't modified)" };
+ case LUA_STR_CHECK: return { "LUA_STR_CHECK", "LUA_STR_CHECK", "139: byte luaNameIndex (check to ensure LUA string isn't used)" };
+ case DRIVER_CHECK: return { "DRIVER_CHECK", "DRIVER_CHECK", "113: uint Seed + byte[20] SHA1 + byte driverNameIndex (check to ensure driver isn't loaded)" };
+ case TIMING_CHECK: return { "TIMING_CHECK", "TIMING_CHECK", "87: empty (check to ensure GetTickCount() isn't detoured)" };
+ case PROC_CHECK: return { "PROC_CHECK", "PROC_CHECK", "126: uint Seed + byte[20] SHA1 + byte moluleNameIndex + byte procNameIndex + uint Offset + byte Len (check to ensure proc isn't detoured)" };
+ case MODULE_CHECK: return { "MODULE_CHECK", "MODULE_CHECK", "217: uint Seed + byte[20] SHA1 (check to ensure module isn't injected)" };
+ default: throw std::out_of_range("value");
+ }
+}
+
+template <>
+TC_API_EXPORT size_t EnumUtils<WardenCheckType>::Count() { return 9; }
+
+template <>
+TC_API_EXPORT WardenCheckType EnumUtils<WardenCheckType>::FromIndex(size_t index)
+{
+ switch (index)
+ {
+ case 0: return MEM_CHECK;
+ case 1: return PAGE_CHECK_A;
+ case 2: return PAGE_CHECK_B;
+ case 3: return MPQ_CHECK;
+ case 4: return LUA_STR_CHECK;
+ case 5: return DRIVER_CHECK;
+ case 6: return TIMING_CHECK;
+ case 7: return PROC_CHECK;
+ case 8: return MODULE_CHECK;
+ default: throw std::out_of_range("index");
+ }
+}
+}
+}
diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp
index 16bfea63ad5..17992ddddba 100644
--- a/src/server/scripts/Commands/cs_reload.cpp
+++ b/src/server/scripts/Commands/cs_reload.cpp
@@ -47,7 +47,6 @@ EndScriptData */
#include "SmartAI.h"
#include "SpellMgr.h"
#include "SupportMgr.h"
-#include "WardenCheckMgr.h"
#include "WaypointManager.h"
#include "World.h"
@@ -160,7 +159,6 @@ public:
{ "support", rbac::RBAC_PERM_COMMAND_RELOAD_SUPPORT_SYSTEM, true, &HandleReloadSupportSystemCommand, "" },
{ "trainer", rbac::RBAC_PERM_COMMAND_RELOAD_TRAINER, true, &HandleReloadTrainerCommand, "" },
{ "trinity_string", rbac::RBAC_PERM_COMMAND_RELOAD_TRINITY_STRING, true, &HandleReloadTrinityStringCommand, "" },
- { "warden_action", rbac::RBAC_PERM_COMMAND_RELOAD_WARDEN_ACTION, true, &HandleReloadWardenactionCommand, "" },
{ "waypoint_scripts", rbac::RBAC_PERM_COMMAND_RELOAD_WAYPOINT_SCRIPTS, true, &HandleReloadWpScriptsCommand, "" },
{ "waypoint_data", rbac::RBAC_PERM_COMMAND_RELOAD_WAYPOINT_DATA, true, &HandleReloadWpCommand, "" },
{ "vehicle_template", rbac::RBAC_PERM_COMMAND_RELOAD_VEHICLE_TEMPLATE, true, &HandleReloadVehicleTemplateCommand, "" },
@@ -697,21 +695,6 @@ public:
return true;
}
- static bool HandleReloadWardenactionCommand(ChatHandler* handler, char const* /*args*/)
- {
- if (!sWorld->getBoolConfig(CONFIG_WARDEN_ENABLED))
- {
- handler->SendSysMessage("Warden system disabled by config - reloading warden_action skipped.");
- handler->SetSentErrorMessage(true);
- return false;
- }
-
- TC_LOG_INFO("misc", "Re-Loading warden_action Table!");
- sWardenCheckMgr->LoadWardenOverrides();
- handler->SendGlobalGMSysMessage("DB table `warden_action` reloaded.");
- return true;
- }
-
static bool HandleReloadTrainerCommand(ChatHandler* handler, char const* /*args*/)
{
TC_LOG_INFO("misc", "Re-Loading `trainer` Table!");