OregonCore  revision 3611e8a-git
Your Favourite TBC server
WardenBase.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the OregonCore Project. See AUTHORS file for Copyright information
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the
6  * Free Software Foundation; either version 2 of the License, or (at your
7  * option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "Common.h"
19 #include "WorldPacket.h"
20 #include "WorldSession.h"
21 #include "Log.h"
22 #include "Opcodes.h"
23 #include "ByteBuffer.h"
24 #include <openssl/sha.h>
25 #include "World.h"
26 #include "Util.h"
27 #include "WardenBase.h"
28 #include "WardenWin.h"
29 
30 WardenBase::WardenBase() : iCrypto(16), oCrypto(16), m_WardenCheckTimer(10000/*10 sec*/), m_WardenKickTimer(0), m_WardenDataSent(false), m_initialized(false)
31 {
32 }
33 
35 {
36  delete[] Module->CompressedData;
37  delete Module;
38  Module = NULL;
39 }
40 
41 void WardenBase::Init(WorldSession* /*pClient*/, BigNumber* /*K*/)
42 {
43  ASSERT(false);
44 }
45 
47 {
48  ASSERT(false);
49  return NULL;
50 }
51 
53 {
54  ASSERT(false);
55 }
56 
58 {
59  ASSERT(false);
60 }
61 
63 {
64  ASSERT(false);
65 }
66 
68 {
69  ASSERT(false);
70 }
71 
73 {
74  ASSERT(false);
75 }
76 
78 {
79  sLog.outDebug("Send module to client");
80 
81  // Create packet structure
83 
84  uint32 size_left = Module->CompressedSize;
85  uint32 pos = 0;
86  uint16 burst_size;
87  while (size_left > 0)
88  {
89  burst_size = size_left < 500 ? size_left : 500;
91  pkt.DataSize = burst_size;
92  memcpy(pkt.Data, &Module->CompressedData[pos], burst_size);
93  size_left -= burst_size;
94  pos += burst_size;
95 
96  EncryptData((uint8*)&pkt, burst_size + 3);
97  WorldPacket pkt1(SMSG_WARDEN_DATA, burst_size + 3);
98  pkt1.append((uint8*)&pkt, burst_size + 3);
99  Client->SendPacket(&pkt1);
100  }
101 }
102 
104 {
105  sLog.outDebug("Request module");
106 
107  // Create packet structure
108  WardenModuleUse Request;
110 
111  memcpy(Request.Module_Id, Module->ID, 16);
112  memcpy(Request.Module_Key, Module->Key, 16);
113  Request.Size = Module->CompressedSize;
114 
115  // Encrypt with warden RC4 key.
116  EncryptData((uint8*)&Request, sizeof(WardenModuleUse));
117 
119  pkt.append((uint8*)&Request, sizeof(WardenModuleUse));
120  Client->SendPacket(&pkt);
121 }
122 
124 {
125  if (m_initialized)
126  {
127  uint32 ticks = getMSTime();
128  uint32 diff = ticks - m_WardenTimer;
129  m_WardenTimer = ticks;
130 
131  if (m_WardenDataSent)
132  {
133  // 1.5 minutes after send packet
134  uint32 maxClientResponseDelay = sWorld.getConfig(CONFIG_WARDEN_CLIENT_RESPONSE_DELAY);
135  if ((m_WardenKickTimer > maxClientResponseDelay * IN_MILLISECONDS) && sWorld.getConfig(CONFIG_WARDEN_KICK))
136  Client->KickPlayer();
137  else
138  m_WardenKickTimer += diff;
139  }
140  else if (m_WardenCheckTimer > 0)
141  {
142  if (diff >= m_WardenCheckTimer)
143  {
144  RequestData();
146  }
147  else
148  m_WardenCheckTimer -= diff;
149  }
150  }
151 }
152 
154 {
155  iCrypto.UpdateData(Len, Buffer);
156 }
157 
159 {
160  oCrypto.UpdateData(Len, Buffer);
161 }
162 
163 bool WardenBase::IsValidCheckSum(uint32 checksum, const uint8* Data, const uint16 Length)
164 {
165  uint32 newchecksum = BuildChecksum(Data, Length);
166 
167  if (checksum != newchecksum)
168  {
169  sLog.outWarden("CHECKSUM IS NOT VALID");
170  return false;
171  }
172  else
173  {
174  sLog.outDebug("CHECKSUM IS VALID");
175  return true;
176  }
177 }
178 
180 {
181  uint8 hash[20];
182  SHA1(data, dataLen, hash);
183  uint32 checkSum = 0;
184  for (uint8 i = 0; i < 5; ++i)
185  checkSum = checkSum ^ *(uint32*)(&hash[0] + i * 4);
186  return checkSum;
187 }
188 
190 {
191  if (!m_Warden || recv_data.empty())
192  return;
193 
194  m_Warden->DecryptData(const_cast<uint8*>(recv_data.contents()), recv_data.size());
195  uint8 Opcode;
196  recv_data >> Opcode;
197  sLog.outDebug("Got packet, opcode %02X, size %lu", Opcode, recv_data.size());
198  recv_data.hexlike();
199 
200  switch (Opcode)
201  {
203  m_Warden->SendModuleToClient();
204  break;
206  m_Warden->RequestHash();
207  break;
209  m_Warden->HandleData(recv_data);
210  break;
212  sLog.outDebug("NYI WARDEN_CMSG_MEM_CHECKS_RESULT received!");
213  break;
215  m_Warden->HandleHashResult(recv_data);
216  m_Warden->InitializeModule();
217  break;
219  sLog.outDebug("NYI WARDEN_CMSG_MODULE_FAILED received!");
220  break;
221  default:
222  sLog.outError("Got unknown warden opcode %02X of size %lu.", Opcode, recv_data.size() - 1);
223  break;
224  }
225 }
static uint32 BuildChecksum(const uint8 *data, uint32 dataLen)
Definition: WardenBase.cpp:179
ClientWardenModule * Module
Definition: WardenBase.h:126
virtual void InitializeModule()
Definition: WardenBase.cpp:52
const uint8 * contents() const
Definition: ByteBuffer.h:331
static bool IsValidCheckSum(uint32 checksum, const uint8 *Data, const uint16 Length)
Definition: WardenBase.cpp:163
bool m_WardenDataSent
Definition: WardenBase.h:124
uint8 Module_Key[16]
Definition: WardenBase.h:55
void DecryptData(uint8 *Buffer, uint32 Len)
Definition: WardenBase.cpp:153
virtual ClientWardenModule * GetModuleForClient(WorldSession *session)
Definition: WardenBase.cpp:46
uint32 CompressedSize
Definition: WardenBase.h:82
uint32 getMSTime()
Definition: Timer.h:32
#define sLog
Log class singleton.
Definition: Log.h:187
NULL Dbg ErrDB Arena Chat Char Map MMap false
Definition: Log.cpp:556
uint32 m_WardenKickTimer
Definition: WardenBase.h:123
SARC4 oCrypto
Definition: WardenBase.h:121
void SendPacket(WorldPacket const *packet)
uint32 m_WardenTimer
Definition: WardenBase.h:125
virtual void HandleHashResult(ByteBuffer &buff)
Definition: WardenBase.cpp:62
uint8 * CompressedData
Definition: WardenBase.h:83
void Update()
Definition: WardenBase.cpp:123
void SendModuleToClient()
Definition: WardenBase.cpp:77
ACE_UINT8 uint8
Definition: Define.h:73
uint8 Module_Id[16]
Definition: WardenBase.h:54
bool empty() const
Definition: ByteBuffer.h:340
size_t size() const
Definition: ByteBuffer.h:336
void RequestModule()
Definition: WardenBase.cpp:103
SARC4 iCrypto
Definition: WardenBase.h:120
void UpdateData(int len, uint8 *data)
Definition: SARC4.cpp:46
virtual void Init(WorldSession *pClient, BigNumber *K)
Definition: WardenBase.cpp:41
void hexlike() const
Definition: ByteBuffer.h:451
void HandleWardenDataOpcode(WorldPacket &recv_data)
Definition: WardenBase.cpp:189
WorldSession * Client
Definition: WardenBase.h:116
void append(const std::string &str)
Definition: ByteBuffer.h:358
virtual ~WardenBase()
Definition: WardenBase.cpp:34
uint32 m_WardenCheckTimer
Definition: WardenBase.h:122
virtual void RequestHash()
Definition: WardenBase.cpp:57
#define ASSERT
Definition: Errors.h:33
#define sWorld
Definition: World.h:860
void EncryptData(uint8 *Buffer, uint32 Len)
Definition: WardenBase.cpp:158
ACE_UINT16 uint16
Definition: Define.h:72
ACE_UINT32 uint32
Definition: Define.h:71
bool m_initialized
Definition: WardenBase.h:127
virtual void RequestData()
Definition: WardenBase.cpp:67
virtual void HandleData(ByteBuffer &buff)
Definition: WardenBase.cpp:72