From 47b76b422c612615bd1ca8343ff6df8f93cfc856 Mon Sep 17 00:00:00 2001 From: CPunch Date: Tue, 18 Aug 2020 19:11:31 -0500 Subject: [PATCH] added sanity checks --- src/CNLoginServer.cpp | 18 ++++++++++++++++++ src/CNProtocol.hpp | 2 +- src/CNShardServer.cpp | 1 - src/CNShardServer.hpp | 2 +- src/ChatManager.cpp | 3 +++ src/PlayerManager.cpp | 37 ++++++++++++++++++++++++++++++------- 6 files changed, 53 insertions(+), 10 deletions(-) diff --git a/src/CNLoginServer.cpp b/src/CNLoginServer.cpp index 405f539..728f466 100644 --- a/src/CNLoginServer.cpp +++ b/src/CNLoginServer.cpp @@ -19,6 +19,9 @@ CNLoginServer::CNLoginServer(uint16_t p) { void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) { switch (data->type) { case P_CL2LS_REQ_LOGIN: { + if (data->size != sizeof(sP_CL2LS_REQ_LOGIN)) + return; // ignore the malformed packet + sP_CL2LS_REQ_LOGIN* login = (sP_CL2LS_REQ_LOGIN*)data->buf; sP_LS2CL_REP_LOGIN_SUCC* response = (sP_LS2CL_REP_LOGIN_SUCC*)xmalloc(sizeof(sP_LS2CL_REP_LOGIN_SUCC)); uint64_t cachedKey = sock->getEKey(); // so we can still send the response packet with the correct key @@ -110,6 +113,9 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) { break; } case P_CL2LS_REQ_CHECK_CHAR_NAME: { + if (data->size != sizeof(sP_CL2LS_REQ_CHECK_CHAR_NAME)) + return; + // naughty words allowed!!!!!!!! (also for some reason, the client will always show 'Player 0' if you manually type a name. It will show up for other connected players though) sP_CL2LS_REQ_CHECK_CHAR_NAME* nameCheck = (sP_CL2LS_REQ_CHECK_CHAR_NAME*)data->buf; sP_LS2CL_REP_CHECK_CHAR_NAME_SUCC* response = (sP_LS2CL_REP_CHECK_CHAR_NAME_SUCC*)xmalloc(sizeof(sP_LS2CL_REP_CHECK_CHAR_NAME_SUCC)); @@ -127,6 +133,9 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) { break; } case P_CL2LS_REQ_SAVE_CHAR_NAME: { + if (data->size != sizeof(sP_CL2LS_REQ_SAVE_CHAR_NAME)) + return; + sP_CL2LS_REQ_SAVE_CHAR_NAME* save = (sP_CL2LS_REQ_SAVE_CHAR_NAME*)data->buf; sP_LS2CL_REP_SAVE_CHAR_NAME_SUCC* response = (sP_LS2CL_REP_SAVE_CHAR_NAME_SUCC*)xmalloc(sizeof(sP_LS2CL_REP_SAVE_CHAR_NAME_SUCC)); @@ -146,6 +155,9 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) { break; } case P_CL2LS_REQ_CHAR_CREATE: { + if (data->size != sizeof(sP_CL2LS_REQ_CHAR_CREATE)) + return; + sP_CL2LS_REQ_CHAR_CREATE* character = (sP_CL2LS_REQ_CHAR_CREATE*)data->buf; sP_LS2CL_REP_CHAR_CREATE_SUCC* response = (sP_LS2CL_REP_CHAR_CREATE_SUCC*)xmalloc(sizeof(sP_LS2CL_REP_CHAR_CREATE_SUCC)); @@ -194,6 +206,9 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) { break; } case P_CL2LS_REQ_CHAR_SELECT: { + if (data->size != sizeof(sP_CL2LS_REQ_CHAR_SELECT)) + return; + // character selected sP_CL2LS_REQ_CHAR_SELECT* chararacter = (sP_CL2LS_REQ_CHAR_SELECT*)data->buf; sP_LS2CL_REP_CHAR_SELECT_SUCC* response = (sP_LS2CL_REP_CHAR_SELECT_SUCC*)xmalloc(sizeof(sP_LS2CL_REP_CHAR_SELECT_SUCC)); @@ -209,6 +224,9 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) { break; } case P_CL2LS_REQ_SHARD_SELECT: { + if (data->size != sizeof(sP_CL2LS_REQ_SHARD_SELECT)) + return; + // tell client to connect to the shard server sP_CL2LS_REQ_SHARD_SELECT* shard = (sP_CL2LS_REQ_SHARD_SELECT*)data->buf; sP_LS2CL_REP_SHARD_SELECT_SUCC* response = (sP_LS2CL_REP_SHARD_SELECT_SUCC*)xmalloc(sizeof(sP_LS2CL_REP_SHARD_SELECT_SUCC)); diff --git a/src/CNProtocol.hpp b/src/CNProtocol.hpp index 4399b6a..e587683 100644 --- a/src/CNProtocol.hpp +++ b/src/CNProtocol.hpp @@ -41,7 +41,7 @@ /* Packets format (sent from the client): - [4 bytes] - size of packet (including these 4 bytes!) + [4 bytes] - size of packet including the 4 byte packet type [size bytes] - Encrypted packet (byte swapped && xor'd with 8 byte key; see CNSocketEncryption) [4 bytes] - packet type (which is a combination of the first 4 bytes of the packet and a checksum in some versions) [structure] diff --git a/src/CNShardServer.cpp b/src/CNShardServer.cpp index 6f4a4ba..8165dcf 100644 --- a/src/CNShardServer.cpp +++ b/src/CNShardServer.cpp @@ -29,5 +29,4 @@ void CNShardServer::killConnection(CNSocket* cns) { PlayerManager::removePlayer(cns); CNSharedData::erasePlayer(cachedPlr.SerialKey); - std::cout << U16toU8(cachedPlr.PCStyle.szFirstName) << " " << U16toU8(cachedPlr.PCStyle.szLastName) << " left" << std::endl; } \ No newline at end of file diff --git a/src/CNShardServer.hpp b/src/CNShardServer.hpp index 1b85731..09b01f3 100644 --- a/src/CNShardServer.hpp +++ b/src/CNShardServer.hpp @@ -34,10 +34,10 @@ enum SHARDPACKETID { #define REGISTER_SHARD_PACKET(pactype, handlr) CNShardServer::ShardPackets[pactype] = handlr; -// WARNING: THERE CAN ONLY BE ONE OF THESE SERVERS AT A TIME!!!!!! TODO: change players & packet handlers to be non-static class CNShardServer : public CNServer { private: static void handlePacket(CNSocket* sock, CNPacketData* data); + public: static std::map ShardPackets; diff --git a/src/ChatManager.cpp b/src/ChatManager.cpp index f09ea82..82dbf63 100644 --- a/src/ChatManager.cpp +++ b/src/ChatManager.cpp @@ -15,6 +15,9 @@ void ChatManager::chatHandler(CNSocket* sock, CNPacketData* data) { } void ChatManager::emoteHandler(CNSocket* sock, CNPacketData* data) { + if (data->size != sizeof(sP_CL2FE_REQ_PC_AVATAR_EMOTES_CHAT)) + return; // ignore the malformed packet + // you can dance with friends!!!!!!!! sP_CL2FE_REQ_PC_AVATAR_EMOTES_CHAT* emote = (sP_CL2FE_REQ_PC_AVATAR_EMOTES_CHAT*)data->buf; diff --git a/src/PlayerManager.cpp b/src/PlayerManager.cpp index 6276791..96e03d4 100644 --- a/src/PlayerManager.cpp +++ b/src/PlayerManager.cpp @@ -27,6 +27,9 @@ void PlayerManager::addPlayer(CNSocket* key, Player plr) { players[key] = PlayerView(); players[key].viewable = std::list(); players[key].plr = plr; + + std::cout << U16toU8(plr.PCStyle.szFirstName) << U16toU8(plr.PCStyle.szLastName) << " has joined!" << std::endl; + std::cout << players.size() << " players" << std::endl; } void PlayerManager::removePlayer(CNSocket* key) { @@ -44,6 +47,9 @@ void PlayerManager::removePlayer(CNSocket* key) { } players.erase(key); + + std::cout << U16toU8(cachedView.plr.PCStyle.szFirstName) << U16toU8(cachedView.plr.PCStyle.szLastName) << " has left!" << std::endl; + std::cout << players.size() << " players" << std::endl; } Player PlayerManager::getPlayer(CNSocket* key) { @@ -137,6 +143,9 @@ void PlayerManager::updatePlayerPosition(CNSocket* sock, int X, int Y, int Z) { } void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) { + if (data->size != sizeof(sP_CL2FE_REQ_PC_ENTER)) + return; // ignore the malformed packet + sP_CL2FE_REQ_PC_ENTER* enter = (sP_CL2FE_REQ_PC_ENTER*)data->buf; sP_FE2CL_REP_PC_ENTER_SUCC* response = (sP_FE2CL_REP_PC_ENTER_SUCC*)xmalloc(sizeof(sP_FE2CL_REP_PC_ENTER_SUCC)); @@ -196,6 +205,9 @@ void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) { } void PlayerManager::loadPlayer(CNSocket* sock, CNPacketData* data) { + if (data->size != sizeof(sP_CL2FE_REQ_PC_LOADING_COMPLETE)) + return; // ignore the malformed packet + sP_CL2FE_REQ_PC_LOADING_COMPLETE* complete = (sP_CL2FE_REQ_PC_LOADING_COMPLETE*)data->buf; sP_FE2CL_REP_PC_LOADING_COMPLETE_SUCC* response = (sP_FE2CL_REP_PC_LOADING_COMPLETE_SUCC*)xmalloc(sizeof(sP_FE2CL_REP_PC_LOADING_COMPLETE_SUCC)); @@ -210,6 +222,9 @@ void PlayerManager::loadPlayer(CNSocket* sock, CNPacketData* data) { } void PlayerManager::movePlayer(CNSocket* sock, CNPacketData* data) { + if (data->size != sizeof(sP_CL2FE_REQ_PC_MOVE)) + return; // ignore the malformed packet + sP_CL2FE_REQ_PC_MOVE* moveData = (sP_CL2FE_REQ_PC_MOVE*)data->buf; updatePlayerPosition(sock, moveData->iX, moveData->iY, moveData->iZ); @@ -239,16 +254,12 @@ void PlayerManager::movePlayer(CNSocket* sock, CNPacketData* data) { } void PlayerManager::stopPlayer(CNSocket* sock, CNPacketData* data) { + if (data->size != sizeof(sP_CL2FE_REQ_PC_STOP)) + return; // ignore the malformed packet + sP_CL2FE_REQ_PC_STOP* stopData = (sP_CL2FE_REQ_PC_STOP*)data->buf; updatePlayerPosition(sock, stopData->iX, stopData->iY, stopData->iZ); - DEBUGLOG( - std::cout << "P_CL2FE_REQ_PC_STOP:" << std::endl; - std::cout << "\tX: " << stopData->iX << std::endl; - std::cout << "\tY: " << stopData->iY << std::endl; - std::cout << "\tZ: " << stopData->iZ << std::endl; - ) - uint64_t tm = getTime(); for (CNSocket* otherSock : players[sock].viewable) { @@ -268,6 +279,9 @@ void PlayerManager::stopPlayer(CNSocket* sock, CNPacketData* data) { } void PlayerManager::jumpPlayer(CNSocket* sock, CNPacketData* data) { + if (data->size != sizeof(sP_CL2FE_REQ_PC_JUMP)) + return; // ignore the malformed packet + sP_CL2FE_REQ_PC_JUMP* jumpData = (sP_CL2FE_REQ_PC_JUMP*)data->buf; updatePlayerPosition(sock, jumpData->iX, jumpData->iY, jumpData->iZ); @@ -296,6 +310,9 @@ void PlayerManager::jumpPlayer(CNSocket* sock, CNPacketData* data) { } void PlayerManager::movePlatformPlayer(CNSocket* sock, CNPacketData* data) { + if (data->size != sizeof(sP_CL2FE_REQ_PC_MOVEPLATFORM)) + return; // ignore the malformed packet + sP_CL2FE_REQ_PC_MOVEPLATFORM* platformData = (sP_CL2FE_REQ_PC_MOVEPLATFORM*)data->buf; updatePlayerPosition(sock, platformData->iX, platformData->iY, platformData->iZ); @@ -328,6 +345,9 @@ void PlayerManager::movePlatformPlayer(CNSocket* sock, CNPacketData* data) { } void PlayerManager::gotoPlayer(CNSocket* sock, CNPacketData* data) { + if (data->size != sizeof(sP_CL2FE_REQ_PC_GOTO)) + return; // ignore the malformed packet + sP_CL2FE_REQ_PC_GOTO* gotoData = (sP_CL2FE_REQ_PC_GOTO*)data->buf; sP_FE2CL_REP_PC_GOTO_SUCC* response = (sP_FE2CL_REP_PC_GOTO_SUCC*)xmalloc(sizeof(sP_FE2CL_REP_PC_GOTO_SUCC)); @@ -346,6 +366,9 @@ void PlayerManager::gotoPlayer(CNSocket* sock, CNPacketData* data) { } void PlayerManager::setSpecialPlayer(CNSocket* sock, CNPacketData* data) { + if (data->size != sizeof(sP_CL2FE_GM_REQ_PC_SET_VALUE)) + return; // ignore the malformed packet + sP_CL2FE_GM_REQ_PC_SET_VALUE* setData = (sP_CL2FE_GM_REQ_PC_SET_VALUE*)data->buf; sP_FE2CL_GM_REP_PC_SET_VALUE* response = (sP_FE2CL_GM_REP_PC_SET_VALUE*)xmalloc(sizeof(sP_FE2CL_GM_REP_PC_SET_VALUE));