diff --git a/dCommon/MD5.cpp b/dCommon/MD5.cpp index 36c0d2cf..d20dbd6b 100644 --- a/dCommon/MD5.cpp +++ b/dCommon/MD5.cpp @@ -115,6 +115,14 @@ MD5::MD5(const std::string &text) finalize(); } +// raw md5 construstor +MD5::MD5(const char * input, size_type length) +{ + init(); + update(input, length); + finalize(); +} + ////////////////////////////// void MD5::init() diff --git a/dCommon/MD5.h b/dCommon/MD5.h index 1ada98a5..3b84d6f8 100644 --- a/dCommon/MD5.h +++ b/dCommon/MD5.h @@ -54,6 +54,7 @@ public: MD5(); MD5(const std::string& text); + MD5(const char * input, size_type length); void update(const unsigned char *buf, size_type length); void update(const char *buf, size_type length); MD5& finalize(); diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 5d155f29..1449ed86 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -838,7 +838,31 @@ void HandlePacket(Packet* packet) { case MSG_WORLD_CLIENT_VALIDATION: { std::string username = PacketUtils::ReadString(0x08, packet, true); std::string sessionKey = PacketUtils::ReadString(74, packet, true); + std::string fdbChecksum = PacketUtils::ReadString(packet->length - 33, packet, false); + if (bool(std::stoi(Game::config->GetValue("check_fdb")))) { + std::ifstream fileStream; + fileStream.open ("res/CDServer.fdb", std::ios::binary | std::ios::in); + fileStream.seekg (0, std::ios::end); + uint64_t fileStreamLength = fileStream.tellg(); + fileStream.seekg (0, std::ios::beg); + char * fileStreamData = new char[fileStreamLength + 1]; + fileStream.read(fileStreamData, fileStreamLength); + + *(fileStreamData + (fileStreamLength + 1)) = 0x00; // null terminate the string + + MD5 md5 = MD5(fileStreamData, fileStreamLength + 1); + std::string ourFdbChecksum = md5.hexdigest(); + + Game::logger->Log("WorldServer", "Got client checksum %s and we have server checksum %s. \n", fdbChecksum.c_str(), ourFdbChecksum.c_str()); + + if (fdbChecksum != ourFdbChecksum) { + Game::logger->Log("WorldServer", "Client checksum does not match server checksum.\n"); + Game::server->Disconnect(packet->systemAddress, SERVER_DISCON_KICK); + return; + } + } + //Request the session info from Master: CBITSTREAM; PacketUtils::WriteHeader(bitStream, MASTER, MSG_MASTER_REQUEST_SESSION_KEY); diff --git a/resources/worldconfig.ini b/resources/worldconfig.ini index e5932ec7..1c9b3d84 100644 --- a/resources/worldconfig.ini +++ b/resources/worldconfig.ini @@ -47,3 +47,6 @@ solo_racing=0 # Disables the anti-speedhack system. If you get kicked randomly you might want to disable this, as it might just be lag disable_anti_speedhack=0 + +# 0 or 1, check server fdb (res/CDServer.fdb) against clients +check_fdb=0 \ No newline at end of file