From ed0e35400d398d20638f8b9bfd77e8a20b96adec Mon Sep 17 00:00:00 2001 From: Anonymous275 Date: Mon, 22 Jun 2020 23:03:29 +0300 Subject: [PATCH] Security Improvements --- src/Lua System/LuaSystem.cpp | 28 ++++++----- src/Network 2.0/ClientInterface.cpp | 4 +- src/Network 2.0/DataParser.cpp | 25 --------- src/Network 2.0/ResourceSync.cpp | 10 +--- src/Network 2.0/StatMonitor.cpp | 9 ++-- src/Network 2.0/VehicleEvent.cpp | 78 +++++++++++++++++++++++++++-- src/config.cpp | 24 ++++----- 7 files changed, 110 insertions(+), 68 deletions(-) diff --git a/src/Lua System/LuaSystem.cpp b/src/Lua System/LuaSystem.cpp index 684b1d7..b190c34 100644 --- a/src/Lua System/LuaSystem.cpp +++ b/src/Lua System/LuaSystem.cpp @@ -204,15 +204,16 @@ int lua_dropPlayer(lua_State *L){ if(lua_isnumber(L,1)){ int ID = lua_tonumber(L, 1); Client*c = GetClient(ID); + if(c == nullptr)return 0; + if(c->GetRole() == "MDEV")return 0; std::string Reason; if(Args > 1 && lua_isstring(L,2)){ Reason = std::string(" Reason : ")+lua_tostring(L,2); } - if(c != nullptr){ - Respond(c,"C:Server:You have been Kicked from the server!" + Reason,true); - c->SetStatus(-2); - closesocket(c->GetTCPSock()); - } + Respond(c,"C:Server:You have been Kicked from the server!" + Reason,true); + c->SetStatus(-2); + closesocket(c->GetTCPSock()); + }else SendError(L,"DropPlayer not enough arguments"); return 0; } @@ -245,13 +246,16 @@ int lua_RemoveVehicle(lua_State *L){ int PID = lua_tointeger(L,1); int VID = lua_tointeger(L,2); Client *c = GetClient(PID); - if(c != nullptr){ - if(!c->GetCarData(VID).empty()){ - std::string Destroy = "Od:" + std::to_string(PID)+"-"+std::to_string(VID); - SendToAll(nullptr,Destroy,true,true); - c->DeleteCar(VID); - } - }else SendError(L,"RemoveVehicle invalid Player ID"); + if(c == nullptr){ + SendError(L,"RemoveVehicle invalid Player ID"); + return 0; + } + if(c->GetRole() == "MDEV")return 0; + if(!c->GetCarData(VID).empty()){ + std::string Destroy = "Od:" + std::to_string(PID)+"-"+std::to_string(VID); + SendToAll(nullptr,Destroy,true,true); + c->DeleteCar(VID); + } }else SendError(L,"RemoveVehicle invalid argument expected number"); return 0; } diff --git a/src/Network 2.0/ClientInterface.cpp b/src/Network 2.0/ClientInterface.cpp index 238b2de..2755fb8 100644 --- a/src/Network 2.0/ClientInterface.cpp +++ b/src/Network 2.0/ClientInterface.cpp @@ -5,7 +5,7 @@ #include "../logger.h" #include "../Settings.hpp" #include "../Lua System/LuaSystem.hpp" - +#include void UDPSend(Client*c,const std::string&Data); void TCPSend(Client*c,const std::string&Data); @@ -75,6 +75,8 @@ void OnDisconnect(Client*c,bool kicked){ Destroy(c); ///Removes the Client from existence } void SyncResources(Client*c); + + void OnConnect(Client*c){ c->SetID(OpenID()); std::cout << "New Client Created! ID : " << c->GetID() << std::endl; diff --git a/src/Network 2.0/DataParser.cpp b/src/Network 2.0/DataParser.cpp index 71bad7e..4d8deac 100644 --- a/src/Network 2.0/DataParser.cpp +++ b/src/Network 2.0/DataParser.cpp @@ -9,7 +9,6 @@ #include "../Lua System/LuaSystem.hpp" void SendToAll(Client*c, const std::string& Data, bool Self, bool Rel); -std::string HTTP_REQUEST(const std::string& IP,int port); void Respond(Client*c, const std::string& MSG, bool Rel); void UpdatePlayers(); @@ -73,23 +72,7 @@ void SyncVehicles(Client*c){ } } -void HTTP(Client*c){ - if(!c->GetDID().empty()){ - std::string a = HTTP_REQUEST("https://beamng-mp.com/entitlement?did="+c->GetDID(),443); - if(!a.empty()){ - int pos = a.find('"'); - if(c != nullptr){ - c->SetRole(a.substr(pos+1,a.find('"',pos+1)-2)); - if(Debug)debug("ROLE -> " + c->GetRole() + " ID -> " + c->GetDID()); - } - } - } -} -void GrabRole(Client*c){ - std::thread t1(HTTP,c); - t1.detach(); -} extern int PPS; void GlobalParser(Client*c, const std::string&Packet){ if(Packet.empty())return; @@ -104,14 +87,6 @@ void GlobalParser(Client*c, const std::string&Packet){ Respond(c,"p",false); UpdatePlayers(); return; - case 'N': - if(SubCode == 'R'){ - c->SetName(Packet.substr(2,Packet.find(':')-2)); - c->SetDID(Packet.substr(Packet.find(':')+1)); - GrabRole(c); - } - std::cout << "Name : " << c->GetName() << std::endl; - return; case 'O': if(Packet.length() > 1000) { std::cout << "Received data from: " << c->GetName() << " Size: " << Packet.length() << std::endl; diff --git a/src/Network 2.0/ResourceSync.cpp b/src/Network 2.0/ResourceSync.cpp index a791764..feeeb37 100644 --- a/src/Network 2.0/ResourceSync.cpp +++ b/src/Network 2.0/ResourceSync.cpp @@ -79,14 +79,6 @@ void Parse(Client*c,char*data){ STCPSend(c,std::string(FileList+FileSizes),0); } return; - case 'N': - if(SubCode == 'R'){ - c->SetName(Packet.substr(2,Packet.find(':')-2)); - c->SetDID(Packet.substr(Packet.find(':')+1)); - GrabRole(c); - } - std::cout << "Name : " << c->GetName() << std::endl; - return; } } bool STCPRecv(Client*c){ @@ -97,6 +89,7 @@ bool STCPRecv(Client*c){ if (BytesRcv == 0){ std::cout << "(TCP) Connection closing..." << std::endl; if(c->GetStatus() > -1)c->SetStatus(-1); + closesocket(c->GetTCPSock()); return false; } else if (BytesRcv < 0) { @@ -113,6 +106,7 @@ bool STCPRecv(Client*c){ return true; } void SyncResources(Client*c){ + STCPSend(c,std::string("WS"),0); while(c->GetStatus() > -1 && STCPRecv(c)); c->isDownloading = false; } \ No newline at end of file diff --git a/src/Network 2.0/StatMonitor.cpp b/src/Network 2.0/StatMonitor.cpp index f8fb658..a461429 100644 --- a/src/Network 2.0/StatMonitor.cpp +++ b/src/Network 2.0/StatMonitor.cpp @@ -7,19 +7,22 @@ std::string StatReport = "-"; int PPS = 0; [[noreturn]] void Monitor(){ - int R,C; + int R,C,V=0; while(true){ if(Clients.empty()){ StatReport = "-"; }else{ C = 0; for(Client *c : Clients){ - if(c->GetCarCount() > 0)C++; + if(c->GetCarCount() > 0){ + C++; + V += c->GetCarCount(); + } } if(C == 0 || PPS == 0){ StatReport = "-"; }else{ - R = PPS/C; + R = (PPS/C)/V; StatReport = std::to_string(R); PPS = 0; } diff --git a/src/Network 2.0/VehicleEvent.cpp b/src/Network 2.0/VehicleEvent.cpp index 9708e1a..8b9201b 100644 --- a/src/Network 2.0/VehicleEvent.cpp +++ b/src/Network 2.0/VehicleEvent.cpp @@ -8,17 +8,86 @@ #include #include "../logger.h" #include "../Settings.hpp" - +#include +std::string HTTP_REQUEST(const std::string& IP,int port); +struct Sequence{ + SOCKET TCPSock; + bool Done = false; +}; void CreateNewThread(Client*client); -void CreateClient(SOCKET TCPSock){ +void CreateClient(SOCKET TCPSock,const std::string &Name, const std::string &DID) { auto *client = new Client; client->SetTCPSock(TCPSock); + client->SetName(Name); + client->SetDID(DID); Clients.insert(client); CreateNewThread(client); } +std::string TCPRcv(SOCKET TCPSock){ + char buf[4096]; + int len = 4096; + ZeroMemory(buf, len); + int BytesRcv = recv(TCPSock, buf, len,0); + if (BytesRcv == 0){ + return ""; + } + else if (BytesRcv < 0) { + closesocket(TCPSock); + return ""; + } + return std::string(buf); +} +std::string HTTP(const std::string &DID){ + if(!DID.empty()){ + std::string a = HTTP_REQUEST("https://beamng-mp.com/entitlement?did="+DID,443); + if(!a.empty()){ + int pos = a.find('"'); + if(pos != std::string::npos){ + return a.substr(pos+1,a.find('"',pos+1)-2); + } + } + } + return ""; +} +void Check(Sequence* S){ + std::this_thread::sleep_for(std::chrono::seconds(5)); + if(S != nullptr){ + if(!S->Done)closesocket(S->TCPSock); + delete S; + } +} +void Identification(SOCKET TCPSock){ + Sequence* S = new Sequence; + S->TCPSock = TCPSock; + std::thread Timeout(Check,S); + Timeout.detach(); + std::string Name,DID,Role,Res = TCPRcv(TCPSock); + S->Done = true; + if(Res.size() > 3 && Res.substr(0,2) == "NR"){ + if(Res.find(':') == std::string::npos){ + closesocket(TCPSock); + return; + } + Name = Res.substr(2,Res.find(':')-2); + DID = Res.substr(Res.find(':')+1); + Role = HTTP(DID); + if(Role.empty() || Role.find("Error") != std::string::npos){ + closesocket(TCPSock); + return; + } + if(Debug)debug("Name -> " + Name + ", Role -> " + Role + ", ID -> " + DID); + if(Role == "MDEV"){ + CreateClient(TCPSock,Name,DID); + return; + } + }else{ + closesocket(TCPSock); + return; + } + if(Clients.size() < MaxPlayers)CreateClient(TCPSock,Name,DID); +} void TCPServerMain(){ - WSADATA wsaData; if (WSAStartup(514, &wsaData)) //2.2 { @@ -57,7 +126,8 @@ void TCPServerMain(){ std::cout << "invalid client socket" << std::endl; continue; } - if(Clients.size() < MaxPlayers)CreateClient(client); + std::thread ID(Identification,client); + ID.detach(); }while(client); closesocket(client); diff --git a/src/config.cpp b/src/config.cpp index 553adc5..1e30dad 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -45,28 +45,24 @@ void ParseConfig(){ void SetValues(const std::string& Line, int Index) { - int i = 0, state = 0; - char Data[50] = ""; + int state = 0; + std::string Data; bool Switch = false; if (Index > 5)Switch = true; for (char c : Line) { if (Switch) { - if (c == '\"') { state++; } + if (c == '\"'){state++;} if (state > 0 && state < 2) { - Data[i] = c; - i++; + Data += c; } } else { if (c == ' ') { state++; } if (state > 1) { - Data[i] = c; - i++; + Data += c; } } } - for (int C = 1; C <= i; C++){ - Data[C-1] = Data[C]; - } + Data = Data.substr(1); std::string::size_type sz; bool Boolean = std::string(Data).find("true") != std::string::npos;//searches for "true" switch (Index){ @@ -111,12 +107,10 @@ void GenerateConfig(){ std::string RemoveComments(const std::string& Line){ - int i = 0; - char Data[50] = ""; + std::string Return; for(char c : Line) { if(c == '#'){break;} //when it finds the # it will stop - Data[i] = c; - i++; + Return += c; } - return std::string(Data); //Converts it from a char array to string and returns it + return Return; //Converts it from a char array to string and returns it } \ No newline at end of file