Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
WardenMac.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 "ByteBuffer.h"
7#include "Common.h"
9#include "Log.h"
10#include "MD5.h"
11#include "Opcodes.h"
12#include "Player.h"
13#include "Util.h"
14#include "WardenMac.h"
15#include "WardenModuleMac.h"
16#include "World.h"
17#include "WorldPacket.h"
18#include "WorldSession.h"
19
21
23
24void WardenMac::Init(WorldSession* pClient, SessionKey const& K)
25{
26 _session = pClient;
27 // Generate Warden Key
29 WK.Generate(_inputKey, 16);
30 WK.Generate(_outputKey, 16);
31 /*
32 Seed: 4D808D2C77D905C41A6380EC08586AFE (0x05 packet)
33 Hash: <?> (0x04 packet)
34 Module MD5: 0DBBF209A27B1E279A9FEC5C168A15F7
35 New Client Key: <?>
36 New Cerver Key: <?>
37 */
38 uint8 mod_seed[16] = { 0x4D, 0x80, 0x8D, 0x2C, 0x77, 0xD9, 0x05, 0xC4, 0x1A, 0x63, 0x80, 0xEC, 0x08, 0x58, 0x6A, 0xFE };
39
40 memcpy(_seed, mod_seed, 16);
41
42 _inputCrypto.Init(_inputKey, 16);
43 _outputCrypto.Init(_outputKey, 16);
44 SF_LOG_DEBUG("warden", "Server side warden for client %u initializing...", pClient->GetAccountId());
45 SF_LOG_DEBUG("warden", "C->S Key: %s", SkyFire::Impl::ByteArrayToHexStr(_inputKey, 16).c_str());
46 SF_LOG_DEBUG("warden", "S->C Key: %s", SkyFire::Impl::ByteArrayToHexStr(_outputKey, 16).c_str());
47 SF_LOG_DEBUG("warden", " Seed: %s", SkyFire::Impl::ByteArrayToHexStr(_seed, 16).c_str());
48 SF_LOG_DEBUG("warden", "Loading Module...");
49
51
52 SF_LOG_DEBUG("warden", "Module Key: %s", SkyFire::Impl::ByteArrayToHexStr(_module->Key, 16).c_str());
53 SF_LOG_DEBUG("warden", "Module ID: %s", SkyFire::Impl::ByteArrayToHexStr(_module->Id, 16).c_str());
55}
56
58{
60
62
63 // data assign
64 mod->CompressedSize = len;
65 mod->CompressedData = new uint8[len];
68
69 // md5 hash
70 EVP_MD_CTX* ctx = EVP_MD_CTX_new();
71 EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
72 EVP_DigestUpdate(ctx, mod->CompressedData, len);
73 EVP_DigestFinal_ex(ctx, mod->CompressedData, &len);
74 EVP_MD_CTX_free(ctx);
75
76 return mod;
77}
78
80{
81 SF_LOG_DEBUG("warden", "Initialize module");
82}
83
85{
86 SF_LOG_DEBUG("warden", "Request hash");
87
88 // Create packet structure
89 WardenHashRequest Request;
91 memcpy(Request.Seed, _seed, 16);
92
93 // Encrypt with warden RC4 key.
94 EncryptData((uint8*)&Request, sizeof(WardenHashRequest));
95
97 pkt.append((uint8*)&Request, sizeof(WardenHashRequest));
98 _session->SendPacket(&pkt);
99}
100
101struct keyData {
102 union
103 {
104 struct
105 {
106 uint8 bytes[16];
108
109 struct
110 {
111 int ints[4];
113 };
114};
115
117{
118 // test
119 int keyIn[4];
120
121 keyData mod_seed = { { { { 0x4D, 0x80, 0x8D, 0x2C, 0x77, 0xD9, 0x05, 0xC4, 0x1A, 0x63, 0x80, 0xEC, 0x08, 0x58, 0x6A, 0xFE } } } };
122
123 for (int i = 0; i < 4; ++i)
124 {
125 keyIn[i] = mod_seed.ints.ints[i];
126 }
127
128 int keyOut[4];
129 int keyIn1, keyIn2;
130 keyOut[0] = keyIn[0];
131 keyIn[0] ^= 0xDEADBEEFu;
132 keyIn1 = keyIn[1];
133 keyIn[1] -= 0x35014542u;
134 keyIn2 = keyIn[2];
135 keyIn[2] += 0x5313F22u;
136 keyIn[3] *= 0x1337F00Du;
137 keyOut[1] = keyIn1 - 0x6A028A84;
138 keyOut[2] = keyIn2 + 0xA627E44;
139 keyOut[3] = 0x1337F00D * keyIn[3];
140 // end test
141
142 buff.rpos(buff.wpos());
143
145 sha1.UpdateData((uint8*)keyIn, 16);
146 sha1.Finalize();
147
148 //const uint8 validHash[20] = { 0x56, 0x8C, 0x05, 0x4C, 0x78, 0x1A, 0x97, 0x2A, 0x60, 0x37, 0xA2, 0x29, 0x0C, 0x22, 0xB5, 0x25, 0x71, 0xA0, 0x6F, 0x4E };
149
150 // Verify key
151 if (memcmp(buff.contents() + 1, sha1.GetDigest().data(), 20) != 0)
152 {
153 SF_LOG_WARN("warden", "%s failed hash reply. Action: %s", _session->GetPlayerInfo().c_str(), Penalty().c_str());
154 return;
155 }
156
157 SF_LOG_DEBUG("warden", "Request hash reply: succeed");
158
159 // client 7F96EEFDA5B63D20A4DF8E00CBF48304
160 //const uint8 client_key[16] = { 0x7F, 0x96, 0xEE, 0xFD, 0xA5, 0xB6, 0x3D, 0x20, 0xA4, 0xDF, 0x8E, 0x00, 0xCB, 0xF4, 0x83, 0x04 };
161
162 // server C2B7ADEDFCCCA9C2BFB3F85602BA809B
163 //const uint8 server_key[16] = { 0xC2, 0xB7, 0xAD, 0xED, 0xFC, 0xCC, 0xA9, 0xC2, 0xBF, 0xB3, 0xF8, 0x56, 0x02, 0xBA, 0x80, 0x9B };
164
165 // change keys here
166 memcpy(_inputKey, keyIn, 16);
167 memcpy(_outputKey, keyOut, 16);
168
169 _inputCrypto.Init(_inputKey, 16);
170 _outputCrypto.Init(_outputKey, 16);
171
172 _initialized = true;
173
175}
176
178{
179 SF_LOG_DEBUG("warden", "Request data");
180
181 ByteBuffer buff;
183
184 std::string str = "Test string!";
185
186 buff << uint8(str.size());
187 buff.append(str.c_str(), str.size());
188
189 buff.hexlike();
190
191 // Encrypt with warden RC4 key.
192 EncryptData(buff.contents(), buff.size());
193
194 WorldPacket pkt(SMSG_WARDEN_DATA, buff.size());
195 pkt.append(buff);
196 _session->SendPacket(&pkt);
197
198 _dataSent = true;
199}
200
202{
203 SF_LOG_DEBUG("warden", "Handle data");
204
205 _dataSent = false;
207
208 //uint16 Length;
209 //buff >> Length;
210 //uint32 Checksum;
211 //buff >> Checksum;
212
213 //if (!IsValidCheckSum(Checksum, buff.contents() + buff.rpos(), Length))
214 //{
215 // buff.rpos(buff.wpos());
216 // if (sWorld->GetBoolConfig(CONFIG_BOOL_WARDEN_KICK))
217 // Client->KickPlayer();
218 // return;
219 //}
220
221 //bool found = false;
222
223 std::string str = "Test string!";
224
226 sha1.UpdateData(str);
227 uint32 magic = 0xFEEDFACE; // unsure
228 sha1.UpdateData((uint8*)&magic, 4);
229 sha1.Finalize();
230
231 std::array<uint8, SkyFire::Crypto::SHA1::DIGEST_LENGTH> sha1Hash;
232 buff.read(sha1Hash.data(), sha1Hash.size());
233
234 if (sha1Hash != sha1.GetDigest())
235 {
236 SF_LOG_DEBUG("warden", "Handle data failed: SHA1 hash is wrong!");
237 //found = true;
238 }
239
240 MD5Hash md5;
241 md5.UpdateData((uint8 const*)str.c_str(), str.size());
242 uint8 ourMD5Hash[16];
243 md5.Finalize(ourMD5Hash, 16);
244
245 uint8 theirsMD5Hash[16];
246 buff.read(theirsMD5Hash, 16);
247
248 if (memcmp(ourMD5Hash, theirsMD5Hash, 16))
249 {
250 SF_LOG_DEBUG("warden", "Handle data failed: MD5 hash is wrong!");
251 //found = true;
252 }
253
254 _session->KickPlayer();
255}
std::array< uint8, SESSION_KEY_LENGTH > SessionKey
Definition AuthDefines.h:8
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
#define SF_LOG_WARN(filterType__,...)
Definition Log.h:140
uint32 getMSTime()
Definition Timer.h:12
@ WARDEN_SMSG_HASH_REQUEST
Definition Warden.h:31
@ WARDEN_SMSG_CHEAT_CHECKS_REQUEST
Definition Warden.h:28
uint8 Module_0DBBF209A27B1E279A9FEC5C168A15F7_Key[16]
uint8 Module_0DBBF209A27B1E279A9FEC5C168A15F7_Data[9318]
size_t rpos() const
Definition ByteBuffer.h:470
void hexlike() const
void append(T value)
Definition ByteBuffer.h:147
size_t wpos() const
Definition ByteBuffer.h:483
size_t size() const
Definition ByteBuffer.h:609
uint8 * contents()
Definition ByteBuffer.h:605
Definition MD5.h:14
void UpdateData(const std::string &str)
Definition MD5.cpp:19
void Finalize(const uint8 *data, uint32 len)
Definition MD5.cpp:29
void Generate(uint8 *buf, uint32 sz)
Digest const & GetDigest() const
Definition CryptoHash.h:93
void UpdateData(uint8 const *data, size_t len)
Definition CryptoHash.h:72
Warden()
Definition Warden.cpp:20
void EncryptData(uint8 *buffer, uint32 length)
Definition Warden.cpp:118
SkyFire::Crypto::ARC4 _outputCrypto
Definition Warden.h:125
uint32 _clientResponseTimer
Definition Warden.h:127
SkyFire::Crypto::ARC4 _inputCrypto
Definition Warden.h:124
uint8 _inputKey[16]
Definition Warden.h:121
uint32 _previousTimestamp
Definition Warden.h:129
uint8 _outputKey[16]
Definition Warden.h:122
uint8 _seed[16]
Definition Warden.h:123
void RequestModule()
Definition Warden.cpp:56
ClientWardenModule * _module
Definition Warden.h:130
bool _dataSent
Definition Warden.h:128
bool _initialized
Definition Warden.h:131
std::string Penalty(WardenCheck *check=NULL)
Definition Warden.cpp:165
WorldSession * _session
Definition Warden.h:120
void RequestData()
void RequestHash()
Definition WardenMac.cpp:84
void HandleData(ByteBuffer &buff)
void HandleHashResult(ByteBuffer &buff)
void Init(WorldSession *session, SessionKey const &k)
Definition WardenMac.cpp:24
void InitializeModule()
Definition WardenMac.cpp:79
ClientWardenModule * GetModuleForClient()
Definition WardenMac.cpp:57
Player session in the World.
uint32 GetAccountId() const
@ SMSG_WARDEN_DATA
Definition Opcodes.h:1064
SkyFire::Impl::GenericHash< EVP_sha1, Constants::SHA1_DIGEST_LENGTH_BYTES > SHA1
Definition CryptoHash.h:103
std::string ByteArrayToHexStr(uint8 const *bytes, size_t length, bool reverse=false)
Definition Util.cpp:515
uint8 * CompressedData
Definition Warden.h:85
uint32 CompressedSize
Definition Warden.h:84
uint8 Key[16]
Definition Warden.h:83
uint8 Seed[16]
Definition Warden.h:71
uint32 ints[5]
Definition Warden.cpp:149
uint8 bytes[20]
Definition Warden.cpp:144