Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
Warden.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "AccountMgr.h"
7#include "ByteBuffer.h"
8#include "Common.h"
9#include "Log.h"
10#include "Opcodes.h"
11#include "Player.h"
12#include "Util.h"
13#include "Warden.h"
14#include "World.h"
15#include "WorldPacket.h"
16#include "WorldSession.h"
17#include <openssl/md5.h>
18#include <openssl/sha.h>
19
21
23{
24 delete[] _module->CompressedData;
25 delete _module;
26 _module = NULL;
27 _initialized = false;
28}
29
31{
32 SF_LOG_DEBUG("warden", "Send module to client");
33
34 // Create packet structure
36
37 uint32 sizeLeft = _module->CompressedSize;
38 uint32 pos = 0;
39 uint16 burstSize;
40 while (sizeLeft > 0)
41 {
42 burstSize = sizeLeft < 500 ? sizeLeft : 500;
44 packet.DataSize = burstSize;
45 memcpy(packet.Data, &_module->CompressedData[pos], burstSize);
46 sizeLeft -= burstSize;
47 pos += burstSize;
48
49 EncryptData((uint8*)&packet, burstSize + 3);
50 WorldPacket pkt1(SMSG_WARDEN_DATA, burstSize + 3);
51 pkt1.append((uint8*)&packet, burstSize + 3);
52 _session->SendPacket(&pkt1);
53 }
54}
55
57{
58 SF_LOG_DEBUG("warden", "Request module");
59
60 // Create packet structure
61 WardenModuleUse request;
63
64 memcpy(request.ModuleId, _module->Id, 16);
65 memcpy(request.ModuleKey, _module->Key, 16);
66 request.Size = _module->CompressedSize;
67
68 // Encrypt with warden RC4 key.
69 EncryptData((uint8*)&request, sizeof(WardenModuleUse));
70
72 pkt.append((uint8*)&request, sizeof(WardenModuleUse));
73 _session->SendPacket(&pkt);
74}
75
77{
78 if (_initialized)
79 {
80 uint32 currentTimestamp = getMSTime();
81 uint32 diff = currentTimestamp - _previousTimestamp;
82 _previousTimestamp = currentTimestamp;
83
84 if (_dataSent)
85 {
86 uint32 maxClientResponseDelay = sWorld->getIntConfig(WorldIntConfigs::CONFIG_WARDEN_CLIENT_RESPONSE_DELAY);
87
88 if (maxClientResponseDelay > 0)
89 {
90 // Kick player if client response delays more than set in config
91 if (_clientResponseTimer > maxClientResponseDelay * IN_MILLISECONDS)
92 {
93 SF_LOG_WARN("warden", "%s (latency: %u, IP: %s) exceeded Warden module response delay for more than %s - disconnecting client",
94 _session->GetPlayerInfo().c_str(), _session->GetLatency(), _session->GetRemoteAddress().c_str(), secsToTimeString(maxClientResponseDelay, true).c_str());
95 _session->KickPlayer();
96 }
97 else
99 }
100 }
101 else
102 {
103 if (diff >= _checkTimer)
104 {
105 RequestData();
106 }
107 else
108 _checkTimer -= diff;
109 }
110 }
111}
112
113void Warden::DecryptData(uint8* buffer, uint32 length)
114{
115 _inputCrypto.UpdateData(buffer, length);
116}
117
118void Warden::EncryptData(uint8* buffer, uint32 length)
119{
120 _outputCrypto.UpdateData(buffer, length);
121}
122
123bool Warden::IsValidCheckSum(uint32 checksum, const uint8* data, const uint16 length)
124{
125 uint32 newChecksum = BuildChecksum(data, length);
126
127 if (checksum != newChecksum)
128 {
129 SF_LOG_DEBUG("warden", "CHECKSUM IS NOT VALID");
130 return false;
131 }
132 else
133 {
134 SF_LOG_DEBUG("warden", "CHECKSUM IS VALID");
135 return true;
136 }
137}
138
139struct keyData {
140 union
141 {
142 struct
143 {
146
147 struct
148 {
151 };
152};
153
155{
156 keyData hash;
157 SHA1(data, length, hash.bytes.bytes);
158 uint32 checkSum = 0;
159 for (uint8 i = 0; i < 5; ++i)
160 checkSum = checkSum ^ hash.ints.ints[i];
161
162 return checkSum;
163}
164
165std::string Warden::Penalty(WardenCheck* check /*= NULL*/)
166{
167 WardenActions action;
168
169 if (check)
170 action = check->Action;
171 else
173
174 switch (action)
175 {
177 return "None";
178 break;
180 _session->KickPlayer();
181 return "Kick";
182 break;
184 {
185 std::stringstream duration;
186 duration << sWorld->getIntConfig(WorldIntConfigs::CONFIG_WARDEN_CLIENT_BAN_DURATION) << "s";
187 std::string accountName;
188 AccountMgr::GetName(_session->GetAccountId(), accountName);
189 std::stringstream banReason;
190 banReason << "Warden Anticheat Violation";
191 // Check can be NULL, for example if the client sent a wrong signature in the warden packet (CHECKSUM FAIL)
192 if (check)
193 banReason << ": " << check->Comment << " (CheckId: " << check->CheckId << ")";
194
195 sWorld->BanAccount(BAN_ACCOUNT, accountName, duration.str(), banReason.str(), "Server");
196
197 return "Ban";
198 }
199 default:
200 break;
201 }
202 return "Undefined";
203}
204
206{
207 _warden->DecryptData(recvData.contents(), recvData.size());
208 uint8 opcode;
209 recvData >> opcode;
210 SF_LOG_DEBUG("warden", "Got packet, opcode %02X, size %u", opcode, uint32(recvData.size()));
211 recvData.hexlike();
212
213 switch (opcode)
214 {
216 _warden->SendModuleToClient();
217 break;
219 _warden->RequestHash();
220 break;
222 _warden->HandleData(recvData);
223 break;
225 SF_LOG_DEBUG("warden", "NYI WARDEN_CMSG_MEM_CHECKS_RESULT received!");
226 break;
228 _warden->HandleHashResult(recvData);
229 _warden->InitializeModule();
230 break;
232 SF_LOG_DEBUG("warden", "NYI WARDEN_CMSG_MODULE_FAILED received!");
233 break;
234 default:
235 SF_LOG_DEBUG("warden", "Got unknown warden opcode %02X of size %u.", opcode, uint32(recvData.size() - 1));
236 break;
237 }
238}
@ IN_MILLISECONDS
Definition Common.h:125
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
std::uint16_t uint16
Definition Define.h:78
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
#define SF_LOG_WARN(filterType__,...)
Definition Log.h:140
SkyFire::Crypto::SHA1 SHA1
Definition SRP6.cpp:7
@ BAN_ACCOUNT
uint32 getMSTime()
Definition Timer.h:12
std::string secsToTimeString(uint64 timeInSecs, bool shortText, bool hoursOnly)
Definition Util.cpp:127
@ WARDEN_CMSG_MODULE_MISSING
Definition Warden.h:18
@ WARDEN_CMSG_HASH_RESULT
Definition Warden.h:22
@ WARDEN_CMSG_MODULE_FAILED
Definition Warden.h:23
@ WARDEN_CMSG_CHEAT_CHECKS_RESULT
Definition Warden.h:20
@ WARDEN_CMSG_MODULE_OK
Definition Warden.h:19
@ WARDEN_SMSG_MODULE_CACHE
Definition Warden.h:27
@ WARDEN_SMSG_MODULE_USE
Definition Warden.h:26
@ WARDEN_CMSG_MEM_CHECKS_RESULT
Definition Warden.h:21
WardenActions
@ WARDEN_ACTION_KICK
@ WARDEN_ACTION_BAN
@ WARDEN_ACTION_LOG
static bool GetName(uint32 accountId, std::string &name)
void hexlike() const
void append(T value)
Definition ByteBuffer.h:147
size_t size() const
Definition ByteBuffer.h:609
uint8 * contents()
Definition ByteBuffer.h:605
Warden()
Definition Warden.cpp:20
void EncryptData(uint8 *buffer, uint32 length)
Definition Warden.cpp:118
uint32 _checkTimer
Definition Warden.h:126
void DecryptData(uint8 *buffer, uint32 length)
Definition Warden.cpp:113
SkyFire::Crypto::ARC4 _outputCrypto
Definition Warden.h:125
uint32 _clientResponseTimer
Definition Warden.h:127
SkyFire::Crypto::ARC4 _inputCrypto
Definition Warden.h:124
uint32 _previousTimestamp
Definition Warden.h:129
void RequestModule()
Definition Warden.cpp:56
ClientWardenModule * _module
Definition Warden.h:130
void Update()
Definition Warden.cpp:76
static bool IsValidCheckSum(uint32 checksum, const uint8 *data, const uint16 length)
Definition Warden.cpp:123
void SendModuleToClient()
Definition Warden.cpp:30
bool _dataSent
Definition Warden.h:128
bool _initialized
Definition Warden.h:131
static uint32 BuildChecksum(const uint8 *data, uint32 length)
Definition Warden.cpp:154
std::string Penalty(WardenCheck *check=NULL)
Definition Warden.cpp:165
virtual void RequestData()=0
WorldSession * _session
Definition Warden.h:120
virtual ~Warden()
Definition Warden.cpp:22
void HandleWardenDataOpcode(WorldPacket &recvData)
Definition Warden.cpp:205
Warden * _warden
@ SMSG_WARDEN_DATA
Definition Opcodes.h:1064
#define sWorld
Definition World.h:910
@ CONFIG_WARDEN_CLIENT_FAIL_ACTION
Definition World.h:335
@ CONFIG_WARDEN_CLIENT_RESPONSE_DELAY
Definition World.h:333
@ CONFIG_WARDEN_CLIENT_BAN_DURATION
Definition World.h:336
std::string Comment
enum WardenActions Action
uint8 Data[500]
Definition Warden.h:65
uint8 Command
Definition Warden.h:55
uint32 Size
Definition Warden.h:58
uint8 ModuleId[16]
Definition Warden.h:56
uint8 ModuleKey[16]
Definition Warden.h:57
uint32 ints[5]
Definition Warden.cpp:149
uint8 bytes[20]
Definition Warden.cpp:144