mirror of
https://github.com/BeamMP/BeamMP-Launcher.git
synced 2026-04-06 07:46:18 +00:00
Launcher update to 1.63.5
- async tcp buffer - two way encryption on connect - map security fix - DNS Lookup on connect - fixed bug in beamng security
This commit is contained in:
@@ -6,10 +6,12 @@
|
||||
#include "Curl/http.h"
|
||||
#include <WinSock2.h>
|
||||
#include <WS2tcpip.h>
|
||||
#include "Startup.h"
|
||||
#include "Memory.h"
|
||||
#include "Logger.h"
|
||||
#include <thread>
|
||||
#include <set>
|
||||
|
||||
std::set<std::string>* ConfList = nullptr;
|
||||
bool TCPTerminate = false;
|
||||
int DEFAULT_PORT = 4444;
|
||||
@@ -19,14 +21,25 @@ std::string MStatus;
|
||||
bool once = false;
|
||||
bool ModLoaded;
|
||||
long long ping = -1;
|
||||
Buffer Handler;
|
||||
void StartSync(const std::string &Data){
|
||||
std::string IP = GetAddr(Data.substr(1,Data.find(':')-1));
|
||||
if(IP.find('.') == -1){
|
||||
if(IP == "DNS")UlStatus = Sec("UlConnection Failed! (DNS Lookup Failed)");
|
||||
else UlStatus = Sec("UlConnection Failed! (WSA failed to start)");
|
||||
ListOfMods = "-";
|
||||
Terminate = true;
|
||||
return;
|
||||
}
|
||||
UlStatus = Sec("UlLoading...");
|
||||
TCPTerminate = false;
|
||||
Terminate = false;
|
||||
ConfList->clear();
|
||||
Handler.clear();
|
||||
ping = -1;
|
||||
std::thread GS(TCPGameServer,Data.substr(1,Data.find(':')-1),std::stoi(Data.substr(Data.find(':')+1)));
|
||||
std::thread GS(TCPGameServer,IP,std::stoi(Data.substr(Data.find(':')+1)));
|
||||
GS.detach();
|
||||
info(Sec("Connecting to server"));
|
||||
}
|
||||
void Parse(std::string Data,SOCKET CSocket){
|
||||
char Code = Data.at(0), SubCode = 0;
|
||||
@@ -39,14 +52,11 @@ void Parse(std::string Data,SOCKET CSocket){
|
||||
NetReset();
|
||||
Terminate = true;
|
||||
TCPTerminate = true;
|
||||
//if(!Dev){
|
||||
Data = Code + HTTP_REQUEST(Sec("s1.yourthought.co.uk/servers-info"),3599);
|
||||
//}else Data.clear();
|
||||
Data = Code + HTTP_REQUEST(Sec("https://beammp.com/servers-info"),443);
|
||||
break;
|
||||
case 'C':
|
||||
ListOfMods.clear();
|
||||
StartSync(Data);
|
||||
info(Sec("Connecting to server"));
|
||||
while(ListOfMods.empty() && !Terminate){
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
}
|
||||
@@ -78,6 +88,9 @@ void Parse(std::string Data,SOCKET CSocket){
|
||||
}
|
||||
Data.clear();
|
||||
break;
|
||||
case 'Z':
|
||||
Data = "Z" + GetVer();
|
||||
break;
|
||||
default:
|
||||
Data.clear();
|
||||
break;
|
||||
|
||||
26
src/Network/DNS.cpp
Normal file
26
src/Network/DNS.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
///
|
||||
/// Created by Anonymous275 on 9/25/2020
|
||||
///
|
||||
|
||||
#include <string>
|
||||
#include <winsock.h>
|
||||
#include "Logger.h"
|
||||
std::string GetAddr(const std::string&IP){
|
||||
if(IP.find_first_not_of("0123456789.") == -1)return IP;
|
||||
WSADATA wsaData;
|
||||
hostent *host;
|
||||
if(WSAStartup(514, &wsaData) != 0){
|
||||
error("WSA Startup Failed!");
|
||||
WSACleanup();
|
||||
return "";
|
||||
}
|
||||
host = gethostbyname(IP.c_str());
|
||||
if(!host){
|
||||
error("DNS lookup failed! on " + IP);
|
||||
WSACleanup();
|
||||
return "DNS";
|
||||
}
|
||||
std::string Ret = inet_ntoa(*((struct in_addr *)host->h_addr));
|
||||
WSACleanup();
|
||||
return Ret;
|
||||
}
|
||||
@@ -31,6 +31,7 @@ void ServerSend(std::string Data, bool Rel){
|
||||
int DLen = int(Data.length());
|
||||
if(DLen > 3)C = Data.at(0);
|
||||
if (C == 'O' || C == 'T')Ack = true;
|
||||
if(C == 'W' || C == 'Y' || C == 'V' || C == 'E')Rel = true;
|
||||
if(Ack || Rel){
|
||||
if(Ack || DLen > 1000)SendLarge(Data);
|
||||
else TCPSend(Data);
|
||||
@@ -187,7 +188,6 @@ void TCPGameServer(const std::string& IP, int Port){
|
||||
ServerSend(t,false);
|
||||
S++;
|
||||
}
|
||||
if(S > 3)std::cout << S << std::endl;
|
||||
}while(Res > 0);
|
||||
if(Res == 0)debug(Sec("(Proxy) Connection closing"));
|
||||
else debug(Sec("(Proxy) recv failed error : ") + std::to_string(WSAGetLastError()));
|
||||
|
||||
@@ -95,21 +95,54 @@ void Parse(const std::string& msg){
|
||||
}else return;
|
||||
}
|
||||
}
|
||||
|
||||
std::string HandShake(SOCKET Sock){
|
||||
std::string GenerateM(RSA*key){
|
||||
std::stringstream stream;
|
||||
stream << std::hex << key->n << "g" << key->e << "g" << RSA_E(Sec("IDC"),key->e,key->n);
|
||||
return stream.str();
|
||||
}
|
||||
struct Hold{
|
||||
SOCKET TCPSock{};
|
||||
bool Done = false;
|
||||
};
|
||||
void Check(Hold* S){
|
||||
std::this_thread::sleep_for(std::chrono::seconds(5));
|
||||
if(S != nullptr){
|
||||
if(!S->Done && S->TCPSock != -1){
|
||||
closesocket(S->TCPSock);
|
||||
}
|
||||
}
|
||||
}
|
||||
std::string HandShake(SOCKET Sock,Hold*S,RSA*LKey){
|
||||
S->TCPSock = Sock;
|
||||
std::thread Timeout(Check,S);
|
||||
Timeout.detach();
|
||||
N = 0;E = 0;
|
||||
auto Res = STCPRecv(Sock);
|
||||
std::string msg(Res.first,Res.second);
|
||||
Parse(msg);
|
||||
if(N != 0 && E != 0) {
|
||||
msg = RSA_E("NR" + GetDName() + ":" + GetDID(),E,N);
|
||||
if(!msg.empty()) {
|
||||
STCPSend(Sock,msg);
|
||||
STCPSend(Sock, RSA_E("VC" + GetVer(),E,N));
|
||||
Res = STCPRecv(Sock);
|
||||
msg = Res.first;
|
||||
STCPSend(Sock,GenerateM(LKey));
|
||||
Res = STCPRecv(Sock);
|
||||
msg = std::string(Res.first,Res.second);
|
||||
if(RSA_D(msg,LKey->d,LKey->n) != "HC"){
|
||||
Terminate = true;
|
||||
}
|
||||
}else Terminate = true;
|
||||
S->Done = true;
|
||||
if(Terminate){
|
||||
TCPTerminate = true;
|
||||
UlStatus = Sec("UlDisconnected: full or outdated server");
|
||||
info(Sec("Terminated!"));
|
||||
return "";
|
||||
}
|
||||
msg = RSA_E("NR" + GetDName() + ":" + GetDID(),E,N);
|
||||
if(!msg.empty()) {
|
||||
STCPSend(Sock,msg);
|
||||
STCPSend(Sock, RSA_E("VC" + GetVer(),E,N));
|
||||
Res = STCPRecv(Sock);
|
||||
msg = Res.first;
|
||||
}
|
||||
|
||||
if(N == 0 || E == 0 || msg.size() < 2 || msg.substr(0,2) != "WS"){
|
||||
Terminate = true;
|
||||
TCPTerminate = true;
|
||||
@@ -130,7 +163,11 @@ std::string HandShake(SOCKET Sock){
|
||||
}
|
||||
|
||||
void SyncResources(SOCKET Sock){
|
||||
std::string Ret = HandShake(Sock);
|
||||
RSA*LKey = GenKey();
|
||||
auto* S = new Hold;
|
||||
std::string Ret = HandShake(Sock,S,LKey);
|
||||
delete LKey;
|
||||
delete S;
|
||||
if(Ret.empty())return;
|
||||
|
||||
info(Sec("Checking Resources..."));
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "Security/Enc.h"
|
||||
#include <WS2tcpip.h>
|
||||
#include "Logger.h"
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
#include <string>
|
||||
#include <array>
|
||||
@@ -25,24 +26,36 @@ struct SplitData{
|
||||
};
|
||||
std::set<SplitData*> SplitPackets;
|
||||
std::set<PacketData*> BigDataAcks;
|
||||
int FC(const std::string& s,const std::string& p,int n) {
|
||||
auto i = s.find(p);
|
||||
int j;
|
||||
for (j = 1; j < n && i != std::string::npos; ++j){
|
||||
i = s.find(p, i+1);
|
||||
}
|
||||
if (j == n)return int(i);
|
||||
else return -1;
|
||||
}
|
||||
void ClearAll(){
|
||||
for(SplitData*S : SplitPackets){
|
||||
if(S != nullptr){
|
||||
delete S;
|
||||
S = nullptr;
|
||||
__try{
|
||||
for (SplitData*S : SplitPackets){
|
||||
if (S != nullptr) {
|
||||
delete S;
|
||||
S = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(PacketData*S : BigDataAcks){
|
||||
if(S != nullptr){
|
||||
delete S;
|
||||
S = nullptr;
|
||||
for (PacketData*S : BigDataAcks){
|
||||
if (S != nullptr) {
|
||||
delete S;
|
||||
S = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}__except(1){}
|
||||
SplitPackets.clear();
|
||||
BigDataAcks.clear();
|
||||
}
|
||||
void UDPSend(std::string Data){
|
||||
if(ClientID == -1 || UDPSock == -1)return;
|
||||
Data = Data.substr(0,Data.find(char(0)));
|
||||
if(Data.length() > 400){
|
||||
std::string CMP(Comp(Data));
|
||||
Data = "ABG:" + CMP;
|
||||
@@ -55,7 +68,7 @@ void UDPSend(std::string Data){
|
||||
void LOOP(){
|
||||
while(UDPSock != -1) {
|
||||
for (PacketData* p : BigDataAcks) {
|
||||
if(p != nullptr && p->Tries < 20){
|
||||
if(p != nullptr && p->Tries < 15){
|
||||
p->Tries++;
|
||||
UDPSend(p->Data);
|
||||
}else{
|
||||
@@ -67,14 +80,14 @@ void LOOP(){
|
||||
break;
|
||||
}
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(300));
|
||||
}
|
||||
}
|
||||
|
||||
void AckID(int ID){
|
||||
for(PacketData* p : BigDataAcks){
|
||||
if(p != nullptr && p->ID == ID){
|
||||
p->Tries = 25;
|
||||
p->Tries = 100;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -91,7 +104,8 @@ int SplitID(){
|
||||
else SID++;
|
||||
return SID;
|
||||
}
|
||||
void SendLarge(const std::string&Data){
|
||||
void SendLarge(std::string Data){
|
||||
Data = Data.substr(0,Data.find(char(0)));
|
||||
int ID = PackID();
|
||||
std::string Packet;
|
||||
if(Data.length() > 1000){
|
||||
@@ -99,16 +113,16 @@ void SendLarge(const std::string&Data){
|
||||
int S = 1,Split = int(ceil(float(pckt.length()) / 1000));
|
||||
int SID = SplitID();
|
||||
while(pckt.length() > 1000){
|
||||
Packet = "SC"+std::to_string(S)+"/"+std::to_string(Split)+":"+std::to_string(ID)+"|"+
|
||||
std::to_string(SID)+":"+pckt.substr(0,1000);
|
||||
Packet = "SC|"+std::to_string(S)+"|"+std::to_string(Split)+"|"+std::to_string(ID)+"|"+
|
||||
std::to_string(SID)+"|"+pckt.substr(0,1000);
|
||||
BigDataAcks.insert(new PacketData{ID,Packet,1});
|
||||
UDPSend(Packet);
|
||||
pckt = pckt.substr(1000);
|
||||
S++;
|
||||
ID = PackID();
|
||||
}
|
||||
Packet = "SC"+std::to_string(S)+"/"+std::to_string(Split)+":"+
|
||||
std::to_string(ID)+"|"+std::to_string(SID)+":"+pckt;
|
||||
Packet = "SC|"+std::to_string(S)+"|"+std::to_string(Split)+"|"+
|
||||
std::to_string(ID)+"|"+std::to_string(SID)+"|"+pckt;
|
||||
BigDataAcks.insert(new PacketData{ID,Packet,1});
|
||||
UDPSend(Packet);
|
||||
}else{
|
||||
@@ -117,20 +131,20 @@ void SendLarge(const std::string&Data){
|
||||
UDPSend(Packet);
|
||||
}
|
||||
}
|
||||
std::array<int, 50> HandledIDs;
|
||||
std::array<int, 100> HandledIDs = {-1};
|
||||
int APos = 0;
|
||||
void IDReset(){
|
||||
for(int C = 0;C < 50;C++){
|
||||
for(int C = 0;C < 100;C++){
|
||||
HandledIDs.at(C) = -1;
|
||||
}
|
||||
}
|
||||
bool Handled(int ID){
|
||||
static int Pos = 0;
|
||||
for(int id : HandledIDs){
|
||||
if(id == ID)return true;
|
||||
}
|
||||
if(Pos > 49)Pos = 0;
|
||||
HandledIDs.at(Pos) = ID;
|
||||
Pos++;
|
||||
if(APos > 99)APos = 0;
|
||||
HandledIDs.at(APos) = ID;
|
||||
APos++;
|
||||
return false;
|
||||
}
|
||||
SplitData*GetSplit(int SplitID){
|
||||
@@ -142,22 +156,29 @@ SplitData*GetSplit(int SplitID){
|
||||
return a;
|
||||
}
|
||||
|
||||
void ServerParser(const std::string& Data);
|
||||
|
||||
void HandleChunk(const std::string&Data){
|
||||
int pos1 = int(Data.find(':'))+1,pos2 = int(Data.find(':',pos1)),pos3 = int(Data.find('/'));
|
||||
int pos4 = int(Data.find('|'));
|
||||
int Max = stoi(Data.substr(pos3+1,pos1-pos3-2));
|
||||
int Current = stoi(Data.substr(2,pos3-2));
|
||||
int ID = stoi(Data.substr(pos1,pos4-pos1));
|
||||
int SplitID = stoi(Data.substr(pos4+1,pos2-pos4-1));
|
||||
std::string ack = "TRG:" + Data.substr(pos1,pos4-pos1);
|
||||
int pos = FC(Data,"|",5);
|
||||
if(pos == -1)return;
|
||||
std::stringstream ss(Data.substr(0,pos++));
|
||||
std::string t;
|
||||
int I = -1;
|
||||
//Current Max ID SID
|
||||
std::vector<int> Num(4,0);
|
||||
while (std::getline(ss, t, '|')) {
|
||||
if(I != -1)Num.at(I) = std::stoi(t);
|
||||
I++;
|
||||
}
|
||||
std::string ack = "TRG:" + std::to_string(Num.at(2));
|
||||
UDPSend(ack);
|
||||
if(Handled(ID))return;
|
||||
warn("Handeling Packet ID : " + std::to_string(ID));
|
||||
SplitData* SData = GetSplit(SplitID);
|
||||
SData->Total = Max;
|
||||
SData->ID = SplitID;
|
||||
SData->Fragments.insert(std::make_pair(Current,Data.substr(pos2+1)));
|
||||
if(Handled(Num.at(2))){
|
||||
return;
|
||||
}
|
||||
std::string Packet = Data.substr(pos);
|
||||
SplitData* SData = GetSplit(Num.at(3));
|
||||
SData->Total = Num.at(1);
|
||||
SData->ID = Num.at(3);
|
||||
SData->Fragments.insert(std::make_pair(Num.at(0),Packet));
|
||||
if(SData->Fragments.size() == SData->Total){
|
||||
std::string ToHandle;
|
||||
for(const std::pair<int,std::string>& a : SData->Fragments){
|
||||
@@ -173,9 +194,9 @@ void UDPParser(std::string Packet){
|
||||
if(Packet.substr(0,4) == "ABG:"){
|
||||
Packet = DeComp(Packet.substr(4));
|
||||
}
|
||||
Packet = Packet.substr(0,Packet.find(char(0)));
|
||||
if(Packet.substr(0,4) == "TRG:"){
|
||||
AckID(stoi(Packet.substr(4)));
|
||||
debug(Sec("Got Ack for data"));
|
||||
return;
|
||||
}else if(Packet.substr(0,3) == "BD:"){
|
||||
auto pos = Packet.find(':',4);
|
||||
@@ -194,17 +215,14 @@ void UDPParser(std::string Packet){
|
||||
ServerParser(Packet);
|
||||
}
|
||||
void UDPRcv(){
|
||||
char buf[10240];
|
||||
int len = 10240;
|
||||
sockaddr_in FromServer{};
|
||||
int clientLength = sizeof(FromServer);
|
||||
ZeroMemory(&FromServer, clientLength);
|
||||
ZeroMemory(buf, len);
|
||||
std::string Ret(10240,0);
|
||||
if(UDPSock == -1)return;
|
||||
int Rcv = recvfrom(UDPSock, buf, len, 0, (sockaddr*)&FromServer, &clientLength);
|
||||
int Rcv = recvfrom(UDPSock, &Ret[0], 10240, 0, (sockaddr*)&FromServer, &clientLength);
|
||||
if (Rcv == SOCKET_ERROR)return;
|
||||
std::string Ret(Rcv,0);
|
||||
memcpy_s(&Ret[0],Rcv,buf,Rcv);
|
||||
Ret.resize(Rcv);
|
||||
UDPParser(Ret);
|
||||
}
|
||||
void UDPClientMain(const std::string& IP,int Port){
|
||||
|
||||
@@ -15,22 +15,20 @@ void TCPSend(const std::string&Data){
|
||||
Terminate = true;
|
||||
return;
|
||||
}
|
||||
int BytesSent = send(TCPSock, Data.c_str(), int(Data.length())+1, 0);
|
||||
if (BytesSent == 0){
|
||||
std::string Send = "\n" + Data.substr(0,Data.find(char(0))) + "\n";
|
||||
size_t Sent = send(TCPSock, Send.c_str(), int(Send.size()), 0);
|
||||
if (Sent == 0){
|
||||
debug(Sec("(TCP) Connection closing..."));
|
||||
Terminate = true;
|
||||
return;
|
||||
}
|
||||
else if (BytesSent < 0) {
|
||||
else if (Sent < 0) {
|
||||
debug(Sec("(TCP) send failed with error: ") + std::to_string(WSAGetLastError()));
|
||||
closesocket(TCPSock);
|
||||
Terminate = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ServerParser(const std::string& Data);
|
||||
void TCPRcv(){
|
||||
char buf[4096];
|
||||
int len = 4096;
|
||||
@@ -51,7 +49,7 @@ void TCPRcv(){
|
||||
Terminate = true;
|
||||
return;
|
||||
}
|
||||
ServerParser(std::string(buf));
|
||||
Handler.Handle(std::string(buf));
|
||||
}
|
||||
|
||||
void SyncResources(SOCKET TCPSock);
|
||||
|
||||
Reference in New Issue
Block a user