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, uint8 const *data, const uint16 length)
 
static uint32 BuildChecksum (uint8 const *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 ( )
31 : _session(nullptr), _checkTimer(10000/*10 sec*/), _clientResponseTimer(0),
32 _dataSent(false), _module(nullptr), _initialized(false), _interrupted(false), _checkInProgress(false)
33{
34 memset(_inputKey, 0, sizeof(_inputKey));
35 memset(_outputKey, 0, sizeof(_outputKey));
36 memset(_seed, 0, sizeof(_seed));
37}
uint32 _checkTimer
Definition: Warden.h:145
uint32 _clientResponseTimer
Definition: Warden.h:146
uint8 _inputKey[16]
Definition: Warden.h:140
uint8 _outputKey[16]
Definition: Warden.h:141
uint8 _seed[16]
Definition: Warden.h:142
ClientWardenModule * _module
Definition: Warden.h:148
bool _checkInProgress
Definition: Warden.h:151
bool _dataSent
Definition: Warden.h:147
bool _initialized
Definition: Warden.h:149
WorldSession * _session
Definition: Warden.h:138
bool _interrupted
Definition: Warden.h:150

References _inputKey, _outputKey, and _seed.

◆ ~Warden()

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

References _initialized, _module, and ClientWardenModule::CompressedData.

Member Function Documentation

◆ ApplyPenalty()

void Warden::ApplyPenalty ( uint16  checkId,
std::string const &  reason 
)
197{
198 WardenCheck const* checkData = sWardenCheckMgr->GetWardenDataById(checkId);
199
201 std::string causeMsg;
202 if (checkId && checkData)
203 {
204 action = checkData->Action;
205
206 if (checkData->Comment.empty())
207 {
208 causeMsg = "Warden id " + std::to_string(checkId) + " violation";
209 }
210 else
211 {
212 causeMsg = "Warden: " + checkData->Comment;
213 }
214 }
215 else
216 {
217 // if its not warden check id based, reason must be always provided
218 ASSERT(!reason.empty());
219 causeMsg = reason;
220 }
221
222 switch (action)
223 {
225 break;
227 {
228 _session->KickPlayer(causeMsg.find("Warden") != std::string::npos ? causeMsg : "Warden: " + causeMsg);
229 break;
230 }
232 {
233 std::stringstream duration;
234 duration << sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_BAN_DURATION) << "s";
235 std::string accountName;
237 sBan->BanAccount(accountName, duration.str(), causeMsg, "Server");
238 break;
239 }
240 }
241
242 std::string reportMsg;
243 if (checkId)
244 {
245 if (Player const* plr = _session->GetPlayer())
246 {
247 std::string const reportFormat = "Player {} (guid {}, account id: {}) failed warden {} check ({}). Action: {}";
248 reportMsg = Acore::StringFormat(reportFormat, plr->GetName(), plr->GetGUID().GetCounter(), _session->GetAccountId(),
249 checkId, ((checkData && !checkData->Comment.empty()) ? checkData->Comment : "<warden comment is not set>"),
250 GetWardenActionStr(action));
251 }
252 else
253 {
254 std::string const reportFormat = "Account id: {} failed warden {} check. Action: {}";
255 reportMsg = Acore::StringFormat(reportFormat, _session->GetAccountId(), checkId, GetWardenActionStr(action));
256 }
257 }
258 else
259 {
260 if (Player const* plr = _session->GetPlayer())
261 {
262 std::string const reportFormat = "Player {} (guid {}, account id: {}) triggered warden penalty by reason: {}. Action: {}";
263 reportMsg = Acore::StringFormat(reportFormat, plr->GetName(), plr->GetGUID().GetCounter(), _session->GetAccountId(), causeMsg, GetWardenActionStr(action));
264 }
265 else
266 {
267 std::string const reportFormat = "Account id: {} failed warden {} check. Action: {}";
268 reportMsg = Acore::StringFormat(reportFormat, _session->GetAccountId(), causeMsg, GetWardenActionStr(action));
269 }
270 }
271
272 reportMsg = "Warden: " + reportMsg;
273 LOG_INFO("warden", "> Warden: {}", reportMsg);
274}
#define ASSERT
Definition: Errors.h:68
#define LOG_INFO(filterType__,...)
Definition: Log.h:165
std::uint32_t uint32
Definition: Define.h:107
#define sBan
Definition: BanMgr.h:48
@ CONFIG_WARDEN_CLIENT_BAN_DURATION
Definition: IWorld.h:377
@ CONFIG_WARDEN_CLIENT_FAIL_ACTION
Definition: IWorld.h:376
static std::string GetWardenActionStr(uint32 action)
Definition: Warden.cpp:181
#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
#define sWorld
Definition: World.h:443
std::string StringFormat(FormatString< Args... > fmt, Args &&... args)
Default AC string format function.
Definition: StringFormat.h:34
bool GetName(uint32 accountId, std::string &name)
Definition: AccountMgr.cpp:257
Definition: Player.h:1081
Player * GetPlayer() const
Definition: WorldSession.h:362
uint32 GetAccountId() const
Definition: WorldSession.h:361
void KickPlayer(bool setKicked=true)
Definition: WorldSession.h:400
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::StringFormat(), 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 ( uint8 const *  data,
uint32  length 
)
static
168{
169 keyData hash{};
170 hash.bytes = Acore::Crypto::SHA1::GetDigestOf(data, std::size_t(length));
171 uint32 checkSum = 0;
172
173 for (uint8 i = 0; i < 5; ++i)
174 {
175 checkSum = checkSum ^ hash.ints[i];
176 }
177
178 return checkSum;
179}
std::uint8_t uint8
Definition: Define.h:109
static Digest GetDigestOf(uint8 const *data, std::size_t len)
Definition: CryptoHash.h:48
Definition: Warden.cpp:162
std::array< uint8, 20 > bytes
Definition: Warden.cpp:163

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

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

◆ DecryptData()

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

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 ( )
313{
314 return &_payloadMgr;
315}
WardenPayloadMgr _payloadMgr
Definition: Warden.h:139

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
157{
158 return _initialized;
159}

References _initialized.

◆ IsValidCheckSum()

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

References BuildChecksum(), and LOG_DEBUG.

Referenced by WardenWin::HandleData().

◆ ProcessLuaCheckResponse()

bool Warden::ProcessLuaCheckResponse ( std::string const &  msg)
277{
278 static constexpr char WARDEN_TOKEN[] = "_TW\t";
279 // if msg starts with WARDEN_TOKEN
280 if (msg.rfind(WARDEN_TOKEN, 0) != 0)
281 {
282 return false;
283 }
284
285 uint16 id = 0;
286
287 {
288 std::stringstream msg2(msg);
289 std::string temp;
290 while (msg2 >> temp)
291 {
292 // Found check id - stop loop
293 if (std::stringstream(temp) >> id)
294 break;
295 }
296 }
297
298 if (id < sWardenCheckMgr->GetMaxValidCheckId())
299 {
300 WardenCheck const* check = sWardenCheckMgr->GetWardenDataById(id);
301 if (check && check->Type == LUA_EVAL_CHECK)
302 {
303 ApplyPenalty(id, "");
304 return true;
305 }
306 }
307
308 ApplyPenalty(0, "Sent bogus Lua check response for Warden");
309 return true;
310}
std::uint16_t uint16
Definition: Define.h:108
@ LUA_EVAL_CHECK
Definition: Warden.h:52
void ApplyPenalty(uint16 checkId, std::string const &reason)
Definition: Warden.cpp:196
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 ( )
74{
75 LOG_DEBUG("warden", "Request module");
76
77 // Create packet structure
78 WardenModuleUse request{};
80
81 memcpy(request.ModuleId, _module->Id.data(), 16);
82 memcpy(request.ModuleKey, _module->Key.data(), 16);
83 request.Size = _module->CompressedSize;
84
85 EndianConvert(request.Size);
86
87 // Encrypt with warden RC4 key.
88 EncryptData((uint8*)&request, sizeof(WardenModuleUse));
89
91 pkt.append((uint8*)&request, sizeof(WardenModuleUse));
92 _session->SendPacket(&pkt);
93}
void EndianConvert(T &val)
Definition: ByteConverter.h:47
@ WARDEN_SMSG_MODULE_USE
Definition: Warden.h:38
@ SMSG_WARDEN_DATA
Definition: Opcodes.h:772
Definition: WorldPacket.h:26
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
Definition: WorldSession.cpp:214
Definition: Warden.h:66
uint8 Command
Definition: Warden.h:67
uint32 CompressedSize
Definition: Warden.h:96
std::array< uint8, 16 > Key
Definition: Warden.h:95
std::array< uint8, 16 > Id
Definition: Warden.h:94
void EncryptData(uint8 *buffer, uint32 length)
Definition: Warden.cpp:135

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

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)
96{
97 if (!_initialized)
98 {
99 return;
100 }
101
102 if (_dataSent)
103 {
104 uint32 maxClientResponseDelay = sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_RESPONSE_DELAY);
105 if (maxClientResponseDelay > 0)
106 {
107 if (_clientResponseTimer > maxClientResponseDelay * IN_MILLISECONDS)
108 {
109 _session->KickPlayer("Warden: clientResponseTimer > maxClientResponseDelay (Warden::Update)");
110 }
111 else
112 {
113 _clientResponseTimer += diff;
114 }
115 }
116 }
117 else
118 {
119 if (diff >= _checkTimer)
120 {
122 }
123 else
124 {
125 _checkTimer -= diff;
126 }
127 }
128}
constexpr auto IN_MILLISECONDS
Definition: Common.h:53
@ CONFIG_WARDEN_CLIENT_RESPONSE_DELAY
Definition: IWorld.h:374
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