AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
Warden Class Referenceabstract

#include "Warden.h"

Inheritance diagram for Warden:
WardenMac WardenWin

Public Member Functions

 Warden ()
 
virtual ~Warden ()
 
virtual void Init (WorldSession *session, SessionKey const &k)=0
 
virtual ClientWardenModuleGetModuleForClient ()=0
 
virtual void InitializeModule ()=0
 
virtual void RequestHash ()=0
 
virtual void HandleHashResult (ByteBuffer &buff)=0
 
virtual bool IsCheckInProgress ()=0
 
virtual bool IsInitialized ()
 
virtual void ForceChecks ()=0
 
virtual void RequestChecks ()=0
 
virtual void HandleData (ByteBuffer &buff)=0
 
bool ProcessLuaCheckResponse (std::string const &msg)
 
void SendModuleToClient ()
 
void RequestModule ()
 
void Update (uint32 const diff)
 
void DecryptData (uint8 *buffer, uint32 length)
 
void EncryptData (uint8 *buffer, uint32 length)
 
void ApplyPenalty (uint16 checkId, std::string const &reason)
 
WardenPayloadMgrGetPayloadMgr ()
 

Static Public Member Functions

static bool IsValidCheckSum (uint32 checksum, const uint8 *data, const uint16 length)
 
static uint32 BuildChecksum (const uint8 *data, uint32 length)
 

Private Attributes

WorldSession_session
 
WardenPayloadMgr _payloadMgr
 
uint8 _inputKey [16]
 
uint8 _outputKey [16]
 
uint8 _seed [16]
 
Acore::Crypto::ARC4 _inputCrypto
 
Acore::Crypto::ARC4 _outputCrypto
 
uint32 _checkTimer
 
uint32 _clientResponseTimer
 
bool _dataSent
 
ClientWardenModule_module
 
bool _initialized
 
bool _interrupted
 
bool _checkInProgress
 
uint32 _interruptCounter = 0
 

Friends

class WardenWin
 
class WardenMac
 

Detailed Description

Constructor & Destructor Documentation

◆ Warden()

Warden::Warden ( )
32 : _session(nullptr), _checkTimer(10000/*10 sec*/), _clientResponseTimer(0),
33 _dataSent(false), _module(nullptr), _initialized(false), _interrupted(false), _checkInProgress(false)
34{
35 memset(_inputKey, 0, sizeof(_inputKey));
36 memset(_outputKey, 0, sizeof(_outputKey));
37 memset(_seed, 0, sizeof(_seed));
38}
uint32 _checkTimer
Definition: Warden.h:146
uint32 _clientResponseTimer
Definition: Warden.h:147
uint8 _inputKey[16]
Definition: Warden.h:141
uint8 _outputKey[16]
Definition: Warden.h:142
uint8 _seed[16]
Definition: Warden.h:143
ClientWardenModule * _module
Definition: Warden.h:149
bool _checkInProgress
Definition: Warden.h:152
bool _dataSent
Definition: Warden.h:148
bool _initialized
Definition: Warden.h:150
WorldSession * _session
Definition: Warden.h:139
bool _interrupted
Definition: Warden.h:151

References _inputKey, _outputKey, and _seed.

◆ ~Warden()

Warden::~Warden ( )
virtual
41{
42 delete[] _module->CompressedData;
43 delete _module;
44 _module = nullptr;
45 _initialized = false;
46}
uint8 * CompressedData
Definition: Warden.h:98

References _initialized, _module, and ClientWardenModule::CompressedData.

Member Function Documentation

◆ ApplyPenalty()

void Warden::ApplyPenalty ( uint16  checkId,
std::string const &  reason 
)
198{
199 WardenCheck const* checkData = sWardenCheckMgr->GetWardenDataById(checkId);
200
202 std::string causeMsg;
203 if (checkId && checkData)
204 {
205 action = checkData->Action;
206
207 if (checkData->Comment.empty())
208 {
209 causeMsg = "Warden id " + std::to_string(checkId) + " violation";
210 }
211 else
212 {
213 causeMsg = "Warden: " + checkData->Comment;
214 }
215 }
216 else
217 {
218 // if its not warden check id based, reason must be always provided
219 ASSERT(!reason.empty());
220 causeMsg = reason;
221 }
222
223 switch (action)
224 {
226 break;
228 {
229 _session->KickPlayer(causeMsg.find("Warden") != std::string::npos ? causeMsg : "Warden: " + causeMsg);
230 break;
231 }
233 {
234 std::stringstream duration;
235 duration << sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_BAN_DURATION) << "s";
236 std::string accountName;
238 sBan->BanAccount(accountName, duration.str(), causeMsg, "Server");
239 break;
240 }
241 }
242
243 std::string reportMsg;
244 if (checkId)
245 {
246 if (Player const* plr = _session->GetPlayer())
247 {
248 std::string const reportFormat = "Player {} (guid {}, account id: {}) failed warden {} check ({}). Action: {}";
249 reportMsg = Acore::StringFormatFmt(reportFormat, plr->GetName(), plr->GetGUID().GetCounter(), _session->GetAccountId(),
250 checkId, ((checkData && !checkData->Comment.empty()) ? checkData->Comment : "<warden comment is not set>"),
251 GetWardenActionStr(action));
252 }
253 else
254 {
255 std::string const reportFormat = "Account id: {} failed warden {} check. Action: {}";
256 reportMsg = Acore::StringFormatFmt(reportFormat, _session->GetAccountId(), checkId, GetWardenActionStr(action));
257 }
258 }
259 else
260 {
261 if (Player const* plr = _session->GetPlayer())
262 {
263 std::string const reportFormat = "Player {} (guid {}, account id: {}) triggered warden penalty by reason: {}. Action: {}";
264 reportMsg = Acore::StringFormatFmt(reportFormat, plr->GetName(), plr->GetGUID().GetCounter(), _session->GetAccountId(), causeMsg, GetWardenActionStr(action));
265 }
266 else
267 {
268 std::string const reportFormat = "Account id: {} failed warden {} check. Action: {}";
269 reportMsg = Acore::StringFormatFmt(reportFormat, _session->GetAccountId(), causeMsg, GetWardenActionStr(action));
270 }
271 }
272
273 reportMsg = "Warden: " + reportMsg;
274 LOG_INFO("warden", "> Warden: {}", reportMsg);
275}
#define ASSERT
Definition: Errors.h:68
std::uint32_t uint32
Definition: Define.h:108
#define LOG_INFO(filterType__,...)
Definition: Log.h:167
#define sBan
Definition: BanMgr.h:48
static std::string GetWardenActionStr(uint32 action)
Definition: Warden.cpp:182
#define sWardenCheckMgr
Definition: WardenCheckMgr.h:89
WardenActions
Definition: WardenCheckMgr.h:26
@ WARDEN_ACTION_KICK
Definition: WardenCheckMgr.h:28
@ WARDEN_ACTION_BAN
Definition: WardenCheckMgr.h:29
@ WARDEN_ACTION_LOG
Definition: WardenCheckMgr.h:27
@ CONFIG_WARDEN_CLIENT_BAN_DURATION
Definition: IWorld.h:372
@ CONFIG_WARDEN_CLIENT_FAIL_ACTION
Definition: IWorld.h:371
#define sWorld
Definition: World.h:451
std::string StringFormatFmt(std::string_view fmt, Args &&... args)
Definition: StringFormat.h:44
bool GetName(uint32 accountId, std::string &name)
Definition: AccountMgr.cpp:228
Definition: Player.h:1046
Player * GetPlayer() const
Definition: WorldSession.h:361
uint32 GetAccountId() const
Definition: WorldSession.h:360
void KickPlayer(bool setKicked=true)
Definition: WorldSession.h:399
Definition: WardenCheckMgr.h:44
uint32 Action
Definition: WardenCheckMgr.h:53
std::string Comment
Definition: WardenCheckMgr.h:50

References _session, WardenCheck::Action, ASSERT, WardenCheck::Comment, CONFIG_WARDEN_CLIENT_BAN_DURATION, CONFIG_WARDEN_CLIENT_FAIL_ACTION, WorldSession::GetAccountId(), AccountMgr::GetName(), WorldSession::GetPlayer(), GetWardenActionStr(), WorldSession::KickPlayer(), LOG_INFO, sBan, Acore::StringFormatFmt(), sWardenCheckMgr, sWorld, WARDEN_ACTION_BAN, WARDEN_ACTION_KICK, and WARDEN_ACTION_LOG.

Referenced by WardenWin::HandleData(), WardenMac::HandleHashResult(), WardenWin::HandleHashResult(), and ProcessLuaCheckResponse().

◆ BuildChecksum()

uint32 Warden::BuildChecksum ( const uint8 data,
uint32  length 
)
static
169{
170 keyData hash{};
171 hash.bytes = Acore::Crypto::SHA1::GetDigestOf(data, size_t(length));
172 uint32 checkSum = 0;
173
174 for (uint8 i = 0; i < 5; ++i)
175 {
176 checkSum = checkSum ^ hash.ints[i];
177 }
178
179 return checkSum;
180}
std::uint8_t uint8
Definition: Define.h:110
static Digest GetDigestOf(uint8 const *data, size_t len)
Definition: CryptoHash.h:53
Definition: Warden.cpp:163
std::array< uint8, 20 > bytes
Definition: Warden.cpp:164

References keyData::bytes, and Acore::Impl::GenericHash< HashCreator, DigestLength >::GetDigestOf().

Referenced by WardenWin::InitializeModule(), and IsValidCheckSum().

◆ DecryptData()

void Warden::DecryptData ( uint8 buffer,
uint32  length 
)
132{
133 _inputCrypto.UpdateData(buffer, length);
134}
void UpdateData(uint8 *data, size_t len)
Definition: ARC4.cpp:51
Acore::Crypto::ARC4 _inputCrypto
Definition: Warden.h:144

References _inputCrypto, and Acore::Crypto::ARC4::UpdateData().

◆ EncryptData()

void Warden::EncryptData ( uint8 buffer,
uint32  length 
)

◆ ForceChecks()

virtual void Warden::ForceChecks ( )
pure virtual

Implemented in WardenWin.

◆ GetModuleForClient()

virtual ClientWardenModule * Warden::GetModuleForClient ( )
pure virtual

Implemented in WardenMac, and WardenWin.

◆ GetPayloadMgr()

WardenPayloadMgr * Warden::GetPayloadMgr ( )
314{
315 return &_payloadMgr;
316}
WardenPayloadMgr _payloadMgr
Definition: Warden.h:140

References _payloadMgr.

◆ HandleData()

virtual void Warden::HandleData ( ByteBuffer buff)
pure virtual

Implemented in WardenMac, and WardenWin.

◆ HandleHashResult()

virtual void Warden::HandleHashResult ( ByteBuffer buff)
pure virtual

Implemented in WardenMac, and WardenWin.

◆ Init()

virtual void Warden::Init ( WorldSession session,
SessionKey const &  k 
)
pure virtual

Implemented in WardenMac, and WardenWin.

◆ InitializeModule()

virtual void Warden::InitializeModule ( )
pure virtual

Implemented in WardenMac, and WardenWin.

◆ IsCheckInProgress()

virtual bool Warden::IsCheckInProgress ( )
pure virtual

Implemented in WardenWin.

◆ IsInitialized()

bool Warden::IsInitialized ( )
virtual
158{
159 return _initialized;
160}

References _initialized.

◆ IsValidCheckSum()

bool Warden::IsValidCheckSum ( uint32  checksum,
const uint8 data,
const uint16  length 
)
static
142{
143 uint32 newChecksum = BuildChecksum(data, length);
144
145 if (checksum != newChecksum)
146 {
147 LOG_DEBUG("warden", "CHECKSUM IS NOT VALID");
148 return false;
149 }
150 else
151 {
152 LOG_DEBUG("warden", "CHECKSUM IS VALID");
153 return true;
154 }
155}
#define LOG_DEBUG(filterType__,...)
Definition: Log.h:171
static uint32 BuildChecksum(const uint8 *data, uint32 length)
Definition: Warden.cpp:168

References BuildChecksum(), and LOG_DEBUG.

Referenced by WardenWin::HandleData().

◆ ProcessLuaCheckResponse()

bool Warden::ProcessLuaCheckResponse ( std::string const &  msg)
278{
279 static constexpr char WARDEN_TOKEN[] = "_TW\t";
280 // if msg starts with WARDEN_TOKEN
281 if (msg.rfind(WARDEN_TOKEN, 0) != 0)
282 {
283 return false;
284 }
285
286 uint16 id = 0;
287
288 {
289 std::stringstream msg2(msg);
290 std::string temp;
291 while (msg2 >> temp)
292 {
293 // Found check id - stop loop
294 if (std::stringstream(temp) >> id)
295 break;
296 }
297 }
298
299 if (id < sWardenCheckMgr->GetMaxValidCheckId())
300 {
301 WardenCheck const* check = sWardenCheckMgr->GetWardenDataById(id);
302 if (check && check->Type == LUA_EVAL_CHECK)
303 {
304 ApplyPenalty(id, "");
305 return true;
306 }
307 }
308
309 ApplyPenalty(0, "Sent bogus Lua check response for Warden");
310 return true;
311}
std::uint16_t uint16
Definition: Define.h:109
@ LUA_EVAL_CHECK
Definition: Warden.h:53
void ApplyPenalty(uint16 checkId, std::string const &reason)
Definition: Warden.cpp:197
uint8 Type
Definition: WardenCheckMgr.h:45

References ApplyPenalty(), LUA_EVAL_CHECK, sWardenCheckMgr, and WardenCheck::Type.

◆ RequestChecks()

virtual void Warden::RequestChecks ( )
pure virtual

Implemented in WardenMac, and WardenWin.

Referenced by Update().

◆ RequestHash()

virtual void Warden::RequestHash ( )
pure virtual

Implemented in WardenMac, and WardenWin.

◆ RequestModule()

void Warden::RequestModule ( )
75{
76 LOG_DEBUG("warden", "Request module");
77
78 // Create packet structure
79 WardenModuleUse request{};
81
82 memcpy(request.ModuleId, _module->Id.data(), 16);
83 memcpy(request.ModuleKey, _module->Key.data(), 16);
84 request.Size = _module->CompressedSize;
85
86 EndianConvert(request.Size);
87
88 // Encrypt with warden RC4 key.
89 EncryptData((uint8*)&request, sizeof(WardenModuleUse));
90
92 pkt.append((uint8*)&request, sizeof(WardenModuleUse));
93 _session->SendPacket(&pkt);
94}
void EndianConvert(T &val)
Definition: ByteConverter.h:47
@ WARDEN_SMSG_MODULE_USE
Definition: Warden.h:39
@ SMSG_WARDEN_DATA
Definition: Opcodes.h:772
Definition: WorldPacket.h:27
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
Definition: WorldSession.cpp:207
Definition: Warden.h:67
uint8 Command
Definition: Warden.h:68
uint32 CompressedSize
Definition: Warden.h:97
std::array< uint8, 16 > Key
Definition: Warden.h:96
std::array< uint8, 16 > Id
Definition: Warden.h:95
void EncryptData(uint8 *buffer, uint32 length)
Definition: Warden.cpp:136

References _module, _session, ByteBuffer::append(), WardenModuleUse::Command, ClientWardenModule::CompressedSize, EncryptData(), EndianConvert(), ClientWardenModule::Id, ClientWardenModule::Key, LOG_DEBUG, WorldSession::SendPacket(), SMSG_WARDEN_DATA, and WARDEN_SMSG_MODULE_USE.

Referenced by WardenMac::Init(), and WardenWin::Init().

◆ SendModuleToClient()

void Warden::SendModuleToClient ( )
49{
50 LOG_DEBUG("warden", "Send module to client");
51
52 // Create packet structure
54
55 uint32 sizeLeft = _module->CompressedSize;
56 uint32 pos = 0;
57 uint16 burstSize;
58 while (sizeLeft > 0)
59 {
60 burstSize = sizeLeft < 500 ? sizeLeft : 500;
62 packet.DataSize = burstSize;
63 memcpy(packet.Data, &_module->CompressedData[pos], burstSize);
64 sizeLeft -= burstSize;
65 pos += burstSize;
66
67 EncryptData((uint8*)&packet, burstSize + 3);
68 WorldPacket pkt1(SMSG_WARDEN_DATA, burstSize + 3);
69 pkt1.append((uint8*)&packet, burstSize + 3);
70 _session->SendPacket(&pkt1);
71 }
72}
@ WARDEN_SMSG_MODULE_CACHE
Definition: Warden.h:40
Definition: Warden.h:75
uint16 DataSize
Definition: Warden.h:77
uint8 Command
Definition: Warden.h:76
uint8 Data[500]
Definition: Warden.h:78

References _module, _session, ByteBuffer::append(), WardenModuleTransfer::Command, ClientWardenModule::CompressedData, ClientWardenModule::CompressedSize, WardenModuleTransfer::Data, WardenModuleTransfer::DataSize, EncryptData(), LOG_DEBUG, WorldSession::SendPacket(), SMSG_WARDEN_DATA, and WARDEN_SMSG_MODULE_CACHE.

◆ Update()

void Warden::Update ( uint32 const  diff)
97{
98 if (!_initialized)
99 {
100 return;
101 }
102
103 if (_dataSent)
104 {
105 uint32 maxClientResponseDelay = sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_RESPONSE_DELAY);
106 if (maxClientResponseDelay > 0)
107 {
108 if (_clientResponseTimer > maxClientResponseDelay * IN_MILLISECONDS)
109 {
110 _session->KickPlayer("Warden: clientResponseTimer > maxClientResponseDelay (Warden::Update)");
111 }
112 else
113 {
114 _clientResponseTimer += diff;
115 }
116 }
117 }
118 else
119 {
120 if (diff >= _checkTimer)
121 {
123 }
124 else
125 {
126 _checkTimer -= diff;
127 }
128 }
129}
constexpr auto IN_MILLISECONDS
Definition: Common.h:62
@ CONFIG_WARDEN_CLIENT_RESPONSE_DELAY
Definition: IWorld.h:369
virtual void RequestChecks()=0

References _checkTimer, _clientResponseTimer, _dataSent, _initialized, _session, CONFIG_WARDEN_CLIENT_RESPONSE_DELAY, IN_MILLISECONDS, WorldSession::KickPlayer(), RequestChecks(), and sWorld.

Friends And Related Function Documentation

◆ WardenMac

friend class WardenMac
friend

◆ WardenWin

friend class WardenWin
friend

Member Data Documentation

◆ _checkInProgress

bool Warden::_checkInProgress
private

◆ _checkTimer

uint32 Warden::_checkTimer
private

Referenced by WardenWin::HandleData(), and Update().

◆ _clientResponseTimer

uint32 Warden::_clientResponseTimer
private

◆ _dataSent

◆ _initialized

bool Warden::_initialized
private

◆ _inputCrypto

◆ _inputKey

◆ _interruptCounter

uint32 Warden::_interruptCounter = 0
private

◆ _interrupted

bool Warden::_interrupted
private

◆ _module

◆ _outputCrypto

◆ _outputKey

◆ _payloadMgr

WardenPayloadMgr Warden::_payloadMgr
private

◆ _seed

◆ _session