aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Warden/Warden.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Warden/Warden.cpp')
-rw-r--r--src/server/game/Warden/Warden.cpp166
1 files changed, 86 insertions, 80 deletions
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);
+}