From 31e2f79d8b4c71d6aa6915383734e68f9e65c75c Mon Sep 17 00:00:00 2001 From: Olion Date: Sun, 12 Apr 2015 15:33:46 +0300 Subject: [PATCH] [Warden] Adding DB log, minor refactoring --- src/game/Warden/Warden.cpp | 64 ++++++++++++++++++++++++++++-- src/game/Warden/Warden.h | 12 +++--- src/game/Warden/WardenCheckMgr.cpp | 2 +- src/game/Warden/WardenMac.cpp | 25 ++---------- src/game/Warden/WardenMac.h | 6 --- src/game/Warden/WardenWin.cpp | 34 ++++------------ src/game/Warden/WardenWin.h | 5 --- src/game/WorldHandlers/World.cpp | 13 +++--- src/game/WorldHandlers/World.h | 15 +++---- src/mangosd/mangosd.conf.dist.in | 10 ++++- src/shared/revision.h | 2 +- 11 files changed, 103 insertions(+), 85 deletions(-) diff --git a/src/game/Warden/Warden.cpp b/src/game/Warden/Warden.cpp index 0c6b8c20..28969c2f 100644 --- a/src/game/Warden/Warden.cpp +++ b/src/game/Warden/Warden.cpp @@ -51,6 +51,23 @@ Warden::~Warden() _initialized = false; } +void Warden::RequestHash() +{ + sLog.outWarden("Request hash"); + + // Create packet structure + WardenHashRequest Request; + Request.Command = WARDEN_SMSG_HASH_REQUEST; + memcpy(Request.Seed, _seed, 16); + + // Encrypt with warden RC4 key. + EncryptData((uint8*)&Request, sizeof(WardenHashRequest)); + + WorldPacket pkt(SMSG_WARDEN_DATA, sizeof(WardenHashRequest)); + pkt.append((uint8*)&Request, sizeof(WardenHashRequest)); + _session->SendPacket(&pkt); +} + void Warden::SendModuleToClient() { sLog.outWarden("Send module to client"); @@ -107,7 +124,7 @@ void Warden::Update() if (_dataSent) { - uint32 maxClientResponseDelay = sWorld.getConfig(CONFIG_INT32_WARDEN_CLIENT_RESPONSE_DELAY); + uint32 maxClientResponseDelay = sWorld.getConfig(CONFIG_UINT32_WARDEN_CLIENT_RESPONSE_DELAY); if (maxClientResponseDelay > 0) { @@ -193,7 +210,7 @@ std::string Warden::Penalty(WardenCheck* check /*= NULL*/) if (check) action = check->Action; else - action = WardenActions(sWorld.getConfig(CONFIG_INT32_WARDEN_CLIENT_FAIL_ACTION)); + action = WardenActions(sWorld.getConfig(CONFIG_UINT32_WARDEN_CLIENT_FAIL_ACTION)); switch (action) { @@ -215,7 +232,7 @@ std::string Warden::Penalty(WardenCheck* check /*= NULL*/) if (check) banReason << ": " << check->Comment << " (CheckId: " << check->CheckId << ")"; - sWorld.BanAccount(BAN_ACCOUNT, accountName, sWorld.getConfig(CONFIG_INT32_WARDEN_CLIENT_BAN_DURATION), banReason.str(), "Server"); + sWorld.BanAccount(BAN_ACCOUNT, accountName, sWorld.getConfig(CONFIG_UINT32_WARDEN_CLIENT_BAN_DURATION), banReason.str(), "Warden"); return "Ban"; } @@ -262,3 +279,44 @@ void WorldSession::HandleWardenDataOpcode(WorldPacket& recvData) break; } } + +void Warden::HandleData(ByteBuffer& /*buff*/) +{ + // Set hold off timer, minimum timer should at least be 1 second + uint32 holdOff = sWorld.getConfig(CONFIG_UINT32_WARDEN_CLIENT_CHECK_HOLDOFF); + _checkTimer = (holdOff < 1 ? 1 : holdOff) * IN_MILLISECONDS; +} + +void Warden::LogPositiveToDB(WardenCheck* check) +{ + if (!check || !_session) + return; + + if (uint32(check->Action) < sWorld.getConfig(CONFIG_UINT32_WARDEN_DB_LOGLEVEL)) + return; + + static SqlStatementID insWardenPositive; + + SqlStatement stmt = LoginDatabase.CreateStatement(insWardenPositive, "INSERT INTO warden_log (`check`, `action`, `account`, `guid`, `map`, `position_x`, `position_y`, `position_z`) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); + + stmt.addUInt8(check->CheckId); + stmt.addInt8(check->Action); + stmt.addUInt32(_session->GetAccountId()); + if (Player* pl = _session->GetPlayer()) + { + stmt.addUInt64(pl->GetObjectGuid().GetRawValue()); + stmt.addUInt32(pl->GetMapId()); + stmt.addFloat(pl->GetPositionX()); + stmt.addFloat(pl->GetPositionY()); + stmt.addFloat(pl->GetPositionZ()); + } + else + { + stmt.addUInt64(0); + stmt.addUInt32(0xFFFFFFFF); + stmt.addFloat(0.0f); + stmt.addFloat(0.0f); + stmt.addFloat(0.0f); + } + stmt.Execute(); +} diff --git a/src/game/Warden/Warden.h b/src/game/Warden/Warden.h index 062289fc..9046a070 100644 --- a/src/game/Warden/Warden.h +++ b/src/game/Warden/Warden.h @@ -31,6 +31,7 @@ #include "BigNumber.h" #include "ByteBuffer.h" #include "WardenCheckMgr.h" +#include "Database/DatabaseEnv.h" enum WardenOpcodes { @@ -109,9 +110,6 @@ class WorldSession; class Warden { - friend class WardenWin; - friend class WardenMac; - public: Warden(); virtual ~Warden(); @@ -119,10 +117,10 @@ class Warden virtual void Init(WorldSession* session, BigNumber* k) = 0; virtual ClientWardenModule* GetModuleForClient() = 0; virtual void InitializeModule() = 0; - virtual void RequestHash() = 0; + virtual void RequestHash(); virtual void HandleHashResult(ByteBuffer &buff) = 0; virtual void RequestData() = 0; - virtual void HandleData(ByteBuffer &buff) = 0; + virtual void HandleData(ByteBuffer &buff); void SendModuleToClient(); void RequestModule(); @@ -136,7 +134,9 @@ class Warden // If no check is passed, the default action from config is executed std::string Penalty(WardenCheck* check = NULL); - private: + protected: + void LogPositiveToDB(WardenCheck* check); + WorldSession* _session; uint8 _inputKey[16]; uint8 _outputKey[16]; diff --git a/src/game/Warden/WardenCheckMgr.cpp b/src/game/Warden/WardenCheckMgr.cpp index 4c976c41..287d8653 100644 --- a/src/game/Warden/WardenCheckMgr.cpp +++ b/src/game/Warden/WardenCheckMgr.cpp @@ -95,7 +95,7 @@ void WardenCheckMgr::LoadWardenChecks() wardenCheck->CheckId = id; // Initialize action with default action from config - wardenCheck->Action = WardenActions(sWorld.getConfig(CONFIG_INT32_WARDEN_CLIENT_FAIL_ACTION)); + wardenCheck->Action = WardenActions(sWorld.getConfig(CONFIG_UINT32_WARDEN_CLIENT_FAIL_ACTION)); if (checkType == PAGE_CHECK_A || checkType == PAGE_CHECK_B || checkType == DRIVER_CHECK) { diff --git a/src/game/Warden/WardenMac.cpp b/src/game/Warden/WardenMac.cpp index 10505eb6..f501839a 100644 --- a/src/game/Warden/WardenMac.cpp +++ b/src/game/Warden/WardenMac.cpp @@ -100,23 +100,6 @@ void WardenMac::InitializeModule() sLog.outWarden("Initialize module"); } -void WardenMac::RequestHash() -{ - sLog.outWarden("Request hash"); - - // Create packet structure - WardenHashRequest Request; - Request.Command = WARDEN_SMSG_HASH_REQUEST; - memcpy(Request.Seed, _seed, 16); - - // Encrypt with warden RC4 key. - EncryptData((uint8*)&Request, sizeof(WardenHashRequest)); - - WorldPacket pkt(SMSG_WARDEN_DATA, sizeof(WardenHashRequest)); - pkt.append((uint8*)&Request, sizeof(WardenHashRequest)); - _session->SendPacket(&pkt); -} - struct keyData { union { @@ -171,7 +154,7 @@ void WardenMac::HandleHashResult(ByteBuffer &buff) if (memcmp(buff.contents() + 1, sha1.GetDigest(), 20) != 0) { sLog.outWarden("%s failed hash reply. Action: %s", _session->GetPlayerName(), Penalty().c_str()); - if (sWorld.getConfig(CONFIG_INT32_WARDEN_CLIENT_FAIL_ACTION) != 0) + if (sWorld.getConfig(CONFIG_UINT32_WARDEN_CLIENT_FAIL_ACTION) > uint32(WARDEN_ACTION_LOG)) _session->KickPlayer(); return; } @@ -274,12 +257,10 @@ void WardenMac::HandleData(ByteBuffer &buff) found = true; } - if (found && sWorld.getConfig(CONFIG_INT32_WARDEN_CLIENT_FAIL_ACTION) != 0) + if (found && sWorld.getConfig(CONFIG_UINT32_WARDEN_CLIENT_FAIL_ACTION) > uint32(WARDEN_ACTION_LOG)) _session->KickPlayer(); else sLog.outWarden("SHA1 and MD5 hash verified. Handle data passed."); - // Set hold off timer, minimum timer should at least be 1 second - uint32 holdOff = sWorld.getConfig(CONFIG_INT32_WARDEN_CLIENT_CHECK_HOLDOFF); - _checkTimer = (holdOff < 1 ? 1 : holdOff) * IN_MILLISECONDS; + Warden::HandleData(buff); } diff --git a/src/game/Warden/WardenMac.h b/src/game/Warden/WardenMac.h index 144c4463..01b1dd76 100644 --- a/src/game/Warden/WardenMac.h +++ b/src/game/Warden/WardenMac.h @@ -26,14 +26,9 @@ #ifndef _WARDEN_MAC_H #define _WARDEN_MAC_H -#include "ARC4.h" -#include -#include "BigNumber.h" -#include "ByteBuffer.h" #include "Warden.h" class WorldSession; -class Warden; class WardenMac : public Warden { @@ -44,7 +39,6 @@ class WardenMac : public Warden void Init(WorldSession* session, BigNumber* k) override; ClientWardenModule* GetModuleForClient() override; void InitializeModule() override; - void RequestHash() override; void HandleHashResult(ByteBuffer& buff) override; void RequestData() override; void HandleData(ByteBuffer& buff) override; diff --git a/src/game/Warden/WardenWin.cpp b/src/game/Warden/WardenWin.cpp index ce4fd0f8..9357cb5b 100644 --- a/src/game/Warden/WardenWin.cpp +++ b/src/game/Warden/WardenWin.cpp @@ -134,23 +134,6 @@ void WardenWin::InitializeModule() _session->SendPacket(&pkt); } -void WardenWin::RequestHash() -{ - sLog.outWarden("Request hash"); - - // Create packet structure - WardenHashRequest Request; - Request.Command = WARDEN_SMSG_HASH_REQUEST; - memcpy(Request.Seed, _seed, 16); - - // Encrypt with warden RC4 key. - EncryptData((uint8*)&Request, sizeof(WardenHashRequest)); - - WorldPacket pkt(SMSG_WARDEN_DATA, sizeof(WardenHashRequest)); - pkt.append((uint8*)&Request, sizeof(WardenHashRequest)); - _session->SendPacket(&pkt); -} - void WardenWin::HandleHashResult(ByteBuffer &buff) { buff.rpos(buff.wpos()); @@ -195,7 +178,7 @@ void WardenWin::RequestData() _currentChecks.clear(); // Build check request - for (int32 i = 0; i < sWorld.getConfig(CONFIG_INT32_WARDEN_NUM_MEM_CHECKS); ++i) + for (uint16 i = 0; i < sWorld.getConfig(CONFIG_UINT32_WARDEN_NUM_MEM_CHECKS); ++i) { // If todo list is done break loop (will be filled on next Update() run) if (_memChecksTodo.empty()) @@ -214,7 +197,7 @@ void WardenWin::RequestData() ACE_READ_GUARD(ACE_RW_Mutex, g, sWardenCheckMgr->_checkStoreLock); - for (int32 i = 0; i < sWorld.getConfig(CONFIG_INT32_WARDEN_NUM_OTHER_CHECKS); ++i) + for (uint16 i = 0; i < sWorld.getConfig(CONFIG_UINT32_WARDEN_NUM_OTHER_CHECKS); ++i) { // If todo list is done break loop (will be filled on next Update() run) if (_otherChecksTodo.empty()) @@ -364,10 +347,8 @@ void WardenWin::HandleData(ByteBuffer &buff) uint32 ticksNow = WorldTimer::getMSTime(); uint32 ourTicks = newClientTicks + (ticksNow - _serverTicks); - sLog.outWarden("ServerTicks %u", ticksNow); // Now - sLog.outWarden("RequestTicks %u", _serverTicks); // At request - sLog.outWarden("Ticks %u", newClientTicks); // At response - sLog.outWarden("Ticks diff %u", ourTicks - newClientTicks); + sLog.outWarden("ServerTicks %u, RequestTicks %u, CLientTicks %u", ticksNow, _serverTicks, newClientTicks); // Now, At request, At response + sLog.outWarden("Waittime %u", ourTicks - newClientTicks); } WardenCheckResult* rs; @@ -494,11 +475,10 @@ void WardenWin::HandleData(ByteBuffer &buff) if (checkFailed > 0) { - WardenCheck* check = sWardenCheckMgr->GetWardenDataById(checkFailed); + WardenCheck* check = sWardenCheckMgr->GetWardenDataById(checkFailed); //note it IS NOT NULL here sLog.outWarden("%s failed Warden check %u. Action: %s", _session->GetPlayerName(), checkFailed, Penalty(check).c_str()); + LogPositiveToDB(check); } - // Set hold off timer, minimum timer should at least be 1 second - uint32 holdOff = sWorld.getConfig(CONFIG_INT32_WARDEN_CLIENT_CHECK_HOLDOFF); - _checkTimer = (holdOff < 1 ? 1 : holdOff) * IN_MILLISECONDS; + Warden::HandleData(buff); } diff --git a/src/game/Warden/WardenWin.h b/src/game/Warden/WardenWin.h index abe67d61..16e33f01 100644 --- a/src/game/Warden/WardenWin.h +++ b/src/game/Warden/WardenWin.h @@ -26,10 +26,6 @@ #ifndef _WARDEN_WIN_H #define _WARDEN_WIN_H -#include -#include "ARC4.h" -#include "BigNumber.h" -#include "ByteBuffer.h" #include "Warden.h" #if defined(__GNUC__) @@ -86,7 +82,6 @@ class WardenWin : public Warden void Init(WorldSession* session, BigNumber* K) override; ClientWardenModule* GetModuleForClient() override; void InitializeModule() override; - void RequestHash() override; void HandleHashResult(ByteBuffer &buff) override; void RequestData() override; void HandleData(ByteBuffer &buff) override; diff --git a/src/game/WorldHandlers/World.cpp b/src/game/WorldHandlers/World.cpp index 792d8467..044147f4 100644 --- a/src/game/WorldHandlers/World.cpp +++ b/src/game/WorldHandlers/World.cpp @@ -736,12 +736,13 @@ void World::LoadConfigSettings(bool reload) setConfig(CONFIG_BOOL_WARDEN_WIN_ENABLED, "Warden.WinEnabled", true); setConfig(CONFIG_BOOL_WARDEN_OSX_ENABLED, "Warden.OSXEnabled", false); - setConfig(CONFIG_INT32_WARDEN_NUM_MEM_CHECKS, "Warden.NumMemChecks", 3); - setConfig(CONFIG_INT32_WARDEN_NUM_OTHER_CHECKS, "Warden.NumOtherChecks", 7); - setConfig(CONFIG_INT32_WARDEN_CLIENT_BAN_DURATION, "Warden.BanDuration", 86400); - setConfig(CONFIG_INT32_WARDEN_CLIENT_CHECK_HOLDOFF, "Warden.ClientCheckHoldOff", 30); - setConfig(CONFIG_INT32_WARDEN_CLIENT_FAIL_ACTION, "Warden.ClientCheckFailAction", 0); - setConfig(CONFIG_INT32_WARDEN_CLIENT_RESPONSE_DELAY, "Warden.ClientResponseDelay", 600); + setConfig(CONFIG_UINT32_WARDEN_NUM_MEM_CHECKS, "Warden.NumMemChecks", 3); + setConfig(CONFIG_UINT32_WARDEN_NUM_OTHER_CHECKS, "Warden.NumOtherChecks", 7); + setConfig(CONFIG_UINT32_WARDEN_CLIENT_BAN_DURATION, "Warden.BanDuration", 86400); + setConfig(CONFIG_UINT32_WARDEN_CLIENT_CHECK_HOLDOFF, "Warden.ClientCheckHoldOff", 30); + setConfig(CONFIG_UINT32_WARDEN_CLIENT_FAIL_ACTION, "Warden.ClientCheckFailAction", 0); + setConfig(CONFIG_UINT32_WARDEN_CLIENT_RESPONSE_DELAY, "Warden.ClientResponseDelay", 600); + setConfig(CONFIG_UINT32_WARDEN_DB_LOGLEVEL, "Warden.DBLogLevel", 0); m_relocation_ai_notify_delay = sConfig.GetIntDefault("Visibility.AIRelocationNotifyDelay", 1000u); m_relocation_lower_limit_sq = pow(sConfig.GetFloatDefault("Visibility.RelocationLowerLimit", 10), 2); diff --git a/src/game/WorldHandlers/World.h b/src/game/WorldHandlers/World.h index 01681964..506d95a9 100644 --- a/src/game/WorldHandlers/World.h +++ b/src/game/WorldHandlers/World.h @@ -187,6 +187,14 @@ enum eConfigUInt32Values CONFIG_UINT32_GUID_RESERVE_SIZE_GAMEOBJECT, CONFIG_UINT32_CREATURE_RESPAWN_AGGRO_DELAY, CONFIG_UINT32_LOG_WHISPERS, + // Warden + CONFIG_UINT32_WARDEN_CLIENT_RESPONSE_DELAY, + CONFIG_UINT32_WARDEN_CLIENT_CHECK_HOLDOFF, + CONFIG_UINT32_WARDEN_CLIENT_FAIL_ACTION, + CONFIG_UINT32_WARDEN_CLIENT_BAN_DURATION, + CONFIG_UINT32_WARDEN_NUM_MEM_CHECKS, + CONFIG_UINT32_WARDEN_NUM_OTHER_CHECKS, + CONFIG_UINT32_WARDEN_DB_LOGLEVEL, #ifdef ENABLE_PLAYERBOTS CONFIG_UINT32_PLAYERBOT_MAXBOTS, CONFIG_UINT32_PLAYERBOT_RESTRICTLEVEL, @@ -201,13 +209,6 @@ enum eConfigInt32Values CONFIG_INT32_DEATH_SICKNESS_LEVEL = 0, CONFIG_INT32_QUEST_LOW_LEVEL_HIDE_DIFF, CONFIG_INT32_QUEST_HIGH_LEVEL_HIDE_DIFF, - // Warden - CONFIG_INT32_WARDEN_CLIENT_RESPONSE_DELAY, - CONFIG_INT32_WARDEN_CLIENT_CHECK_HOLDOFF, - CONFIG_INT32_WARDEN_CLIENT_FAIL_ACTION, - CONFIG_INT32_WARDEN_CLIENT_BAN_DURATION, - CONFIG_INT32_WARDEN_NUM_MEM_CHECKS, - CONFIG_INT32_WARDEN_NUM_OTHER_CHECKS, CONFIG_INT32_VALUE_COUNT }; diff --git a/src/mangosd/mangosd.conf.dist.in b/src/mangosd/mangosd.conf.dist.in index b68fa1a1..8038d202 100644 --- a/src/mangosd/mangosd.conf.dist.in +++ b/src/mangosd/mangosd.conf.dist.in @@ -3,7 +3,7 @@ ################################################################################ [MangosdConf] -ConfVersion=2015041201 +ConfVersion=2015041202 ################################################################################ # CONNECTIONS AND DIRECTORIES @@ -1674,6 +1674,13 @@ CharDelete.KeepDays = 30 # Default: 86400 - (24 hours) # 0 - (Permanent ban) # +# Warden.DBLogLevel +# Description: The minimal WardenActions value of Warden check to be logged into realmd.warden_log table. +# WardenActions: 0 - log, 1 - kick, 2 - ban +# +# Deafult: 0 - (Logging any failed check) +# 3 - (Disable DB logging) +# ################################################################################################### Warden.WinEnabled = 1 @@ -1684,6 +1691,7 @@ Warden.ClientResponseDelay = 600 Warden.ClientCheckHoldOff = 30 Warden.ClientCheckFailAction = 1 Warden.BanDuration = 86400 +Warden.DBLogLevel = 0 ################################################################################################################### # ELUNA SETTINGS diff --git a/src/shared/revision.h b/src/shared/revision.h index fb6f5ec4..8f5aa740 100644 --- a/src/shared/revision.h +++ b/src/shared/revision.h @@ -27,5 +27,5 @@ #define REVISION_NR "21000" #define REVISION_DB_CHARACTERS "required_21000_01_warden_action" #define REVISION_DB_MANGOS "required_21000_08_warden_checks" -#define REVISION_DB_REALMD "required_20150409_Playerbot_and_Warden" +#define REVISION_DB_REALMD "required_20150412_warden_db_log" #endif // __REVISION_H__