From b297f0995a8e097c60e67d6372128e65c22f908b Mon Sep 17 00:00:00 2001 From: Teetime Date: Sat, 10 Mar 2012 22:58:38 +0100 Subject: Extended banmaster, now its easier and more comfortable to ban" --- banmasters.cfg | 2 +- src/banmaster/banmaster.cpp | 349 ++++++++++++++++++++++------------- src/banmaster/banmaster.h | 1 + src/engine/server/server.cpp | 59 +++++- src/engine/shared/config.h | 1 + src/engine/shared/network.h | 12 +- src/engine/shared/network_server.cpp | 33 +++- 7 files changed, 305 insertions(+), 152 deletions(-) diff --git a/banmasters.cfg b/banmasters.cfg index 78fb069a..c5397497 100644 --- a/banmasters.cfg +++ b/banmasters.cfg @@ -1,4 +1,4 @@ clear_banmasters add_banmaster banmaster.kottnet.net add_banmaster banmaster.heinrich5991.de - +add_banmaster banmaster.teetw.de diff --git a/src/banmaster/banmaster.cpp b/src/banmaster/banmaster.cpp index d0487763..97eb2aee 100644 --- a/src/banmaster/banmaster.cpp +++ b/src/banmaster/banmaster.cpp @@ -1,234 +1,299 @@ /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ /* If you are missing that file, acquire a complete release at teeworlds.com. */ #include -#include +#include /* atexit() */ + #include #include +#include + +#include +#include +#include +#include +#include #include "banmaster.h" enum { - MAX_BANS=1024, BAN_REREAD_TIME=300, - CFGFLAG_BANMASTER=32 + MAX_BAN_ENTRIES = 10, + MAX_REASON_LENGTH = 128, }; static const char BANMASTER_BANFILE[] = "bans.cfg"; +static const char BANMASTER_BANSSAVEFILE[] = "saved_bans.cfg"; -struct CBan +class CBanmasterBan : public CNetBan { - NETADDR m_Address; - char m_aReason[256]; - int64 m_Expire; +public: + //returns true if address is banned + + bool GetBanInfo(const NETADDR *pAddr, char *pReason, int BufferSize, int *pExpires) + { + CNetHash aHash[17]; + int Length = CNetHash::MakeHashArray(pAddr, aHash); + + // check ban adresses + CBanAddr *pBan = m_BanAddrPool.Find(pAddr, &aHash[Length]); + if(pBan) + { + str_format(pReason, BufferSize, "%s", pBan->m_Info.m_aReason); + *pExpires = pBan->m_Info.m_Expires; + return true; + } + // check ban ranges + for(int i = Length-1; i >= 0; --i) + { + for(CBanRange *pBan = m_BanRangePool.First(&aHash[i]); pBan; pBan = pBan->m_pHashNext) + { + if(NetMatch(&pBan->m_Data, pAddr, i, Length)) + { + str_format(pReason, BufferSize, "%s", pBan->m_Info.m_aReason); + *pExpires = pBan->m_Info.m_Expires; + return true; + } + } + } + + return false; + } +}; + +struct CBanInfo { + char m_aName[16]; + char m_aReason[MAX_REASON_LENGTH]; + NETADDR m_Addr; + int m_RecvTime; +}; + +struct CStats { + unsigned int m_StartTime; + int m_HitsBannedPlayers; + int m_NumRecvBans; + int m_NumRequests; }; -static CBan m_aBans[MAX_BANS]; -static int m_NumBans = 0; -static CNetClient m_Net; -static IConsole *m_pConsole; -static char m_aBindAddr[64] = ""; +CEcon m_Econ; +CNetClient m_Net; +CBanmasterBan m_NetBan; +CBanInfo m_RecvBans[MAX_BAN_ENTRIES]; +CStats m_Stats; + +IConsole *m_pConsole; +IStorage *m_pStorage; +IKernel *m_pKernel; +IConfig *m_pConfig; -CBan* CheckBan(NETADDR *pCheck) +void CleanUp() { - for(int i = 0; i < m_NumBans; i++) - if(net_addr_comp(&m_aBans[i].m_Address, pCheck) == 0) - return &m_aBans[i]; + // Better: RAII? + m_Econ.Shutdown(); - return 0; + delete m_pConsole; + delete m_pConfig; + delete m_pKernel; + delete m_pStorage; } int SendResponse(NETADDR *pAddr, NETADDR *pCheck) { static char aIpBan[sizeof(BANMASTER_IPBAN) + NETADDR_MAXSTRSIZE] = { 0 }; static char *pIpBanContent = aIpBan + sizeof(BANMASTER_IPBAN); + if (!aIpBan[0]) mem_copy(aIpBan, BANMASTER_IPBAN, sizeof(BANMASTER_IPBAN)); - + static CNetChunk p; - + p.m_ClientID = -1; p.m_Address = *pAddr; p.m_Flags = NETSENDFLAG_CONNLESS; - CBan* pBan = CheckBan(pCheck); - if(pBan) + int Expires; + char aReason[128]; + + if(m_NetBan.GetBanInfo(pCheck, aReason, sizeof(aReason), &Expires)) { - net_addr_str(pCheck, pIpBanContent, NETADDR_MAXSTRSIZE, 0); + net_addr_str(pCheck, pIpBanContent, NETADDR_MAXSTRSIZE, false); char *pIpBanReason = pIpBanContent + (str_length(pIpBanContent) + 1); - str_copy(pIpBanReason, pBan->m_aReason, 256); + str_copy(pIpBanReason, aReason, 256); p.m_pData = aIpBan; p.m_DataSize = sizeof(BANMASTER_IPBAN) + str_length(pIpBanContent) + 1 + str_length(pIpBanReason) + 1; m_Net.Send(&p); return 1; } - + return 0; - /*else - { - p.m_DataSize = sizeof(BANMASTER_IPOK); - p.m_pData = BANMASTER_IPOK; - m_Net.Send(&p); - return 0; - }*/ } -void AddBan(NETADDR *pAddr, const char *pReason) +void AddRecvBan(NETADDR *pFromAddr, unsigned char *pData, int Size) { - pAddr->port = 0; + CUnpacker Up; + const char *pIP, *pName, *pReason; - CBan *pBan = CheckBan(pAddr); - char aAddressStr[NETADDR_MAXSTRSIZE]; - net_addr_str(pAddr, aAddressStr, sizeof(aAddressStr), 0); + Up.Reset(pData + sizeof(BANMASTER_IPREPORT), Size - sizeof(BANMASTER_IPREPORT)); - if(pBan) + pName = Up.GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES); + pIP = Up.GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES); + pReason = Up.GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES); + + NETADDR ReportAddr; + if(net_addr_from_str(&ReportAddr, pIP) == 0 && pName[0] && pReason[0]) { - char aAddressStr[NETADDR_MAXSTRSIZE]; - net_addr_str(pAddr, aAddressStr, sizeof(aAddressStr), 0); - dbg_msg("banmaster", "updated ban, ip=%s oldreason='%s' reason='%s'", aAddressStr, pBan->m_aReason, pReason); - - str_copy(pBan->m_aReason, pReason, sizeof(m_aBans[m_NumBans].m_aReason)); - pBan->m_Expire = -1; + for(int i = MAX_BAN_ENTRIES-1; i > 0; i--) + mem_copy(&m_RecvBans[i], &m_RecvBans[i-1], sizeof(m_RecvBans[i])); + + m_RecvBans[0].m_Addr = ReportAddr; + str_copy(m_RecvBans[0].m_aName, pName, sizeof(m_RecvBans[0].m_aName)); + str_copy(m_RecvBans[0].m_aReason, pReason, sizeof(m_RecvBans[0].m_aReason)); + m_RecvBans[0].m_RecvTime = time_timestamp(); + + char aAddr[NETADDR_MAXSTRSIZE]; + char aBuf[256]; + net_addr_str(pFromAddr, aAddr, sizeof(aAddr), false); + str_format(aBuf, sizeof(aBuf), "Received ban from '%s', Name: %s, IP: %s, Reason: %s", aAddr, pName, pIP, pReason); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "banmaster", aBuf); + m_Stats.m_NumRecvBans++; } else - { - if(m_NumBans == MAX_BANS) - { - dbg_msg("banmaster", "error: banmaster is full"); - return; - } - - m_aBans[m_NumBans].m_Address = *pAddr; - str_copy(m_aBans[m_NumBans].m_aReason, pReason, sizeof(m_aBans[m_NumBans].m_aReason)); - m_aBans[m_NumBans].m_Expire = -1; - - dbg_msg("banmaster", "added ban, ip=%s reason='%s'", aAddressStr, m_aBans[m_NumBans].m_aReason); - - m_NumBans++; - } + m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "banmaster", "dropped weird ban message"); } -void ClearBans() +void ReloadBans() { - m_NumBans = 0; + char aBuf[64]; + str_format(aBuf, sizeof(aBuf), "bans_save %s", BANMASTER_BANSSAVEFILE); + m_pConsole->ExecuteLine(aBuf); } -void PurgeBans() +void ConRecvBans(IConsole::IResult *pResult, void *pUser) { - int64 Now = time_get(); - int i = 0; - while(i < m_NumBans) + int Count = 0; + char aBuf[256]; + for(int i = MAX_BAN_ENTRIES-1; i >= 0; i--) { - if(m_aBans[i].m_Expire != -1 && m_aBans[i].m_Expire < Now) - { - // remove ban - char aBuf[NETADDR_MAXSTRSIZE]; - net_addr_str(&m_aBans[i].m_Address, aBuf, sizeof(aBuf), 0); - dbg_msg("banmaster", "ban expired, ip=%s reason='%s'", aBuf, m_aBans[i].m_aReason); - m_aBans[i] = m_aBans[m_NumBans - 1]; - m_NumBans--; - } - else - i++; + if(!m_RecvBans[i].m_aName[0]) + continue; + + char aIP[NETADDR_MAXSTRSIZE]; + net_addr_str(&m_RecvBans[i].m_Addr, aIP, sizeof(aIP), false); + int RecvTime = time_timestamp() - m_RecvBans[i].m_RecvTime; + str_format(aBuf, sizeof(aBuf), "#%d - Name: %s | Reason: %s | IP: %s | Received %d min and %d sec. ago", i, m_RecvBans[i].m_aName, m_RecvBans[i].m_aReason, aIP, RecvTime/60, RecvTime%60); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "banmaster", aBuf); + Count++; } + str_format(aBuf, sizeof(aBuf), "%d Ban(s)", Count); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "banmaster", aBuf); } -void ConBan(IConsole::IResult *pResult, void *pUser) +void ConAddBan(IConsole::IResult *pResult, void *pUser) { - NETADDR Addr; - const char *pStr = pResult->GetString(0); - const char *pReason = ""; - - if(pResult->NumArguments() > 1) - pReason = pResult->GetString(1); - - if(!net_addr_from_str(&Addr, pStr)) - AddBan(&Addr, pReason); + int Index = pResult->GetInteger(0); + if(Index >= 0 && Index < MAX_BAN_ENTRIES && m_RecvBans[Index].m_aName[0]) + { + m_NetBan.BanAddr(&m_RecvBans[Index].m_Addr, pResult->GetInteger(1)*60, pResult->GetString(2)); + } else - dbg_msg("banmaster", "invalid network address to ban, str='%s'", pStr); -} - -void ConUnbanAll(IConsole::IResult *pResult, void *pUser) -{ - ClearBans(); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "banmaster", "Invalid index"); } -void ConSetBindAddr(IConsole::IResult *pResult, void *pUser) -{ - if(m_aBindAddr[0]) - return; - str_copy(m_aBindAddr, pResult->GetString(0), sizeof(m_aBindAddr)); - dbg_msg("banmaster/network", "bound to %s", m_aBindAddr); -} - -void StandardOutput(const char *pLine, void *pUser) +void ConStatus(IConsole::IResult *pResult, void *pUser) { + unsigned int Running = time_timestamp() - m_Stats.m_StartTime; + int Hours = Running / 3600; + char aBuf[512]; + str_format(aBuf, sizeof(aBuf), "Running since %d hours %d min and %d sec. Total received requests: %d (%d hits). %d received bans (%.3f/hour).", + Hours, (Running-Hours*3600) / 60, Running % 60, m_Stats.m_NumRequests, m_Stats.m_HitsBannedPlayers, m_Stats.m_NumRecvBans, (Hours != 0) ? (float)m_Stats.m_NumRecvBans/Hours : m_Stats.m_NumRecvBans); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "banmaster", aBuf); } int main(int argc, const char **argv) // ignore_convention { + atexit(CleanUp); int64 LastUpdate = time_get(); dbg_logger_stdout(); net_init(); - IKernel *pKernel = IKernel::Create(); - IStorage *pStorage = CreateStorage("Teeworlds", IStorage::STORAGETYPE_BASIC, argc, argv); // ignore_convention + m_pKernel = IKernel::Create(); + m_pStorage = CreateStorage("Teeworlds", IStorage::STORAGETYPE_BASIC, argc, argv); // ignore_convention + m_pConfig = CreateConfig(); - m_pConsole = CreateConsole(CFGFLAG_BANMASTER); - m_pConsole->RegisterPrintCallback(2, StandardOutput, 0); - m_pConsole->Register("ban", "s?r", CFGFLAG_BANMASTER, ConBan, 0, "Bans the specified ip"); - m_pConsole->Register("unban_all", "", CFGFLAG_BANMASTER, ConUnbanAll, 0, "Unbans all ips"); - m_pConsole->Register("bind", "s", CFGFLAG_BANMASTER, ConSetBindAddr, 0, "Binds to the specified address"); + m_pConsole = CreateConsole(CFGFLAG_BANMASTER|CFGFLAG_ECON); { bool RegisterFail = false; - RegisterFail = RegisterFail || !pKernel->RegisterInterface(m_pConsole); - RegisterFail = RegisterFail || !pKernel->RegisterInterface(pStorage); + RegisterFail = RegisterFail || !m_pKernel->RegisterInterface(m_pConsole); + RegisterFail = RegisterFail || !m_pKernel->RegisterInterface(m_pStorage); + RegisterFail = RegisterFail || !m_pKernel->RegisterInterface(m_pConfig); if(RegisterFail) return -1; } + //Reset strings + m_pConfig->Init(); + + // Register Commands + m_pConsole->Register("recvbans", "", CFGFLAG_BANMASTER, ConRecvBans, 0, "Show the last received bans"); + m_pConsole->Register("addban", "iir", CFGFLAG_BANMASTER, ConAddBan, 0, "Ban IP by index"); + m_pConsole->Register("status", "", CFGFLAG_BANMASTER, ConStatus, 0, "Show some statistics"); + + + m_NetBan.Init(m_pConsole, m_pStorage); m_pConsole->ExecuteFile(BANMASTER_BANFILE); - + m_Econ.Init(m_pConsole, &m_NetBan); + + m_pConsole->ExecuteFile(BANMASTER_BANSSAVEFILE); + + m_pConsole->StoreCommands(false); + + mem_zero(&m_RecvBans, sizeof(CBanInfo)*MAX_BAN_ENTRIES); + mem_zero(&m_Stats, sizeof(CStats)); + m_Stats.m_StartTime = time_timestamp(); + NETADDR BindAddr; - if(m_aBindAddr[0] && net_host_lookup(m_aBindAddr, &BindAddr, NETTYPE_IPV4) == 0) - { - if(BindAddr.port == 0) - BindAddr.port = BANMASTER_PORT; - } + if(g_Config.m_Bindaddr[0] && net_host_lookup(g_Config.m_Bindaddr, &BindAddr, NETTYPE_ALL) == 0) + BindAddr.port = BANMASTER_PORT; else { mem_zero(&BindAddr, sizeof(BindAddr)); + BindAddr.type = NETTYPE_ALL; BindAddr.port = BANMASTER_PORT; } - - m_Net.Open(BindAddr, 0); - // TODO: check socket for errors + + if(!m_Net.Open(BindAddr, 0)) + { + dbg_msg("banmaster", "couldn't start network"); + return -1; + } dbg_msg("banmaster", "started"); while(1) { m_Net.Update(); - - // process m_aPackets + + // process m_Packets CNetChunk Packet; while(m_Net.Recv(&Packet)) { char aAddressStr[NETADDR_MAXSTRSIZE]; - net_addr_str(&Packet.m_Address, aAddressStr, sizeof(aAddressStr), 0); + net_addr_str(&Packet.m_Address, aAddressStr, sizeof(aAddressStr), false); - if(Packet.m_DataSize >= sizeof(BANMASTER_IPCHECK) && mem_comp(Packet.m_pData, BANMASTER_IPCHECK, sizeof(BANMASTER_IPCHECK)) == 0) + if(Packet.m_DataSize >= (int)sizeof(BANMASTER_IPCHECK) && mem_comp(Packet.m_pData, BANMASTER_IPCHECK, sizeof(BANMASTER_IPCHECK)) == 0) { char *pAddr = (char *)Packet.m_pData + sizeof(BANMASTER_IPCHECK); NETADDR CheckAddr; if(net_addr_from_str(&CheckAddr, pAddr)) { - dbg_msg("banmaster", "dropped weird message, ip=%s checkaddr='%s'", aAddressStr, pAddr); + char aBuf[128]; + str_format(aBuf, sizeof(aBuf), "dropped weird message, ip='%s' checkaddr='%s'", aAddressStr, pAddr); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "banmaster", aBuf); } else { @@ -236,26 +301,46 @@ int main(int argc, const char **argv) // ignore_convention int Banned = SendResponse(&Packet.m_Address, &CheckAddr); - char aBuf[NETADDR_MAXSTRSIZE]; - net_addr_str(&CheckAddr, aBuf, sizeof(aBuf), 0); - dbg_msg("banmaster", "responded to checkmsg, ip=%s checkaddr=%s result=%s", aAddressStr, aBuf, (Banned) ? "ban" : "ok"); + char aIP[NETADDR_MAXSTRSIZE]; + char aBuf[256]; + net_addr_str(&CheckAddr, aIP, sizeof(aIP), false); + str_format(aBuf, sizeof(aBuf), "responded to checkmsg, ip='%s' checkaddr='%s' result=%s", aAddressStr, aIP, (Banned) ? "ban" : "ok"); + if(Banned) + { + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "banmaster", aBuf); + m_Stats.m_HitsBannedPlayers++; + } + else + m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "banmaster", aBuf); + + m_Stats.m_NumRequests++; } } + else if(Packet.m_DataSize >= (int)sizeof(BANMASTER_IPREPORT) && mem_comp(Packet.m_pData, BANMASTER_IPREPORT, sizeof(BANMASTER_IPREPORT)) == 0) + { + //info of a banned client + AddRecvBan(&Packet.m_Address, (unsigned char*)Packet.m_pData, Packet.m_DataSize); + } else - dbg_msg("banmaster", "dropped weird packet, ip=%s", aAddressStr, (char *)Packet.m_pData); + { + char aBuf[128]; + str_format(aBuf, sizeof(aBuf), "dropped weird packet, ip='%s'", aAddressStr, (char *)Packet.m_pData); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "banmaster", aBuf); + } } - + if(time_get() - LastUpdate > time_freq() * BAN_REREAD_TIME) { - ClearBans(); + ReloadBans(); LastUpdate = time_get(); - m_pConsole->ExecuteFile(BANMASTER_BANFILE); } + + m_NetBan.Update(); + m_Econ.Update(); // be nice to the CPU thread_sleep(1); } - + return 0; } - diff --git a/src/banmaster/banmaster.h b/src/banmaster/banmaster.h index f7c645f7..296dc14d 100644 --- a/src/banmaster/banmaster.h +++ b/src/banmaster/banmaster.h @@ -8,5 +8,6 @@ static const int BANMASTER_PORT = 8302; //static const char BANMASTER_IPOK[] = {255, 255, 255, 255, 'i', 'p', 'o', 'k'}; static const char BANMASTER_IPBAN[] = {255, 255, 255, 255, 'i', 'p', 'b', 'a'}; static const char BANMASTER_IPCHECK[] = {255, 255, 255, 255, 'i', 'p', 'c', 'h'}; +static const char BANMASTER_IPREPORT[] = {255, 255, 255, 255, 'i', 'p', 'r', 'e'}; #endif diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 2cb33f36..cd73c5a7 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -266,6 +266,45 @@ void CServerBan::ConBanExt(IConsole::IResult *pResult, void *pUser) int Minutes = pResult->NumArguments()>1 ? clamp(pResult->GetInteger(1), 0, 44640) : 30; const char *pReason = pResult->NumArguments()>2 ? pResult->GetString(2) : "No reason given"; + int CID = -1; + if(StrAllnum(pStr)) + CID = str_toint(pStr); + else + { + NETADDR Addr; + if(net_addr_from_str(&Addr, pStr) == 0) + for(int i = 0; i < MAX_CLIENTS; i++) + if(pThis->NetMatch(&Addr, pThis->Server()->m_NetServer.ClientAddr(i))) + { + CID = i; + break; + } + } + + if(g_Config.m_SvGlobalBantime && CID >= 0 && CID < MAX_CLIENTS && pThis->Server()->m_aClients[CID].m_State == CServer::CClient::STATE_INGAME) + { + char aIP[NETADDR_MAXSTRSIZE]; + net_addr_str(pThis->Server()->m_NetServer.ClientAddr(CID), aIP, sizeof(aIP), 0); + + CPacker P; + P.Reset(); + P.AddRaw(BANMASTER_IPREPORT, sizeof(BANMASTER_IPREPORT)); + P.AddString(pThis->Server()->ClientName(CID), -1); + P.AddString(aIP, -1); + P.AddString(pReason, -1); + + if(!P.Error()) + { + CNetChunk Packet; + Packet.m_ClientID = -1; + Packet.m_Flags = NETSENDFLAG_CONNLESS; + Packet.m_pData = P.Data(); + Packet.m_DataSize = P.Size(); + pThis->Server()->m_NetServer.SendToBanmasters(&Packet); + pThis->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "banmaster", "Reported ban to banmasters"); + } + } + if(StrAllnum(pStr)) { int ClientID = str_toint(pStr); @@ -1207,12 +1246,14 @@ void CServer::PumpNetwork() str_copy(aReason, Up.GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES), sizeof(aReason)); if(net_addr_from_str(&Addr, aIp)) { - dbg_msg("globalbans", "dropped weird message from banmaster"); + Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "globalbans", "dropped weird message from banmaster"); return; } m_ServerBan.BanAddr(&Addr, g_Config.m_SvGlobalBantime * 60, aReason); - dbg_msg("globalbans", "added ban, ip=%s, reason='%s'", aIp, aReason); + char aBuf[256]; + str_format(aBuf, sizeof(aBuf), "added ban, ip=%s, reason='%s'", aIp, aReason); + Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "globalbans", aBuf); } } } @@ -1578,10 +1619,12 @@ void CServer::ConAddBanmaster(IConsole::IResult *pResult, void *pUser) if(Result == 0) pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server/banmaster", "succesfully added banmaster"); - else if (Result == 1) + else if(Result == 1) pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server/banmaster", "invalid address for banmaster / net lookup failed"); - else + else if(Result == 2) pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server/banmaster", "too many banmasters"); + else + pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server/banmaster", "banmaster already exists"); } void CServer::ConBanmasters(IConsole::IResult *pResult, void *pUser) @@ -1789,6 +1832,14 @@ int main(int argc, const char **argv) // ignore_convention pServer->RegisterCommands(); pGameServer->OnConsoleInit(); + /* This banmaster is added into the source of the server that i'm able to ban players even if no banmaster.cfg is used. + * Often serverhoster doesn't add this file because they don't know what it is for and remove it, not + * because they don't want it. If so, set sv_global_bantime to 0 or use a custom banmasters.cfg with "clear_banmasters" + * in first line or in normal config. + * ## For a Teeworlds without bots \o/ ## + */ + pConsole->ExecuteLine("add_banmaster banmaster.teetw.de"); + // execute autoexec file pConsole->ExecuteFile("autoexec.cfg"); diff --git a/src/engine/shared/config.h b/src/engine/shared/config.h index c6d8437f..4200303e 100644 --- a/src/engine/shared/config.h +++ b/src/engine/shared/config.h @@ -22,6 +22,7 @@ enum CFGFLAG_STORE=8, CFGFLAG_MASTER=16, CFGFLAG_ECON=32, + CFGFLAG_BANMASTER=64|CFGFLAG_MASTER, }; #endif diff --git a/src/engine/shared/network.h b/src/engine/shared/network.h index 385f21f2..ea5ed98f 100644 --- a/src/engine/shared/network.h +++ b/src/engine/shared/network.h @@ -248,14 +248,6 @@ public: MAX_BANMASTERS=16 }; - struct CBanInfo - { - NETADDR m_Addr; - int m_Expires; - char m_Reason[128]; - }; - -private: struct CSlot { public: @@ -278,6 +270,7 @@ private: CNetRecvUnpacker m_RecvUnpacker; public: + CNetServer(); int SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_DELCLIENT pfnDelClient, void *pUser); // @@ -301,11 +294,14 @@ public: // void SetMaxClientsPerIP(int Max); + + // int BanmasterAdd(const char *pAddrStr); int BanmasterNum() const; NETADDR* BanmasterGet(int Index); int BanmasterCheck(NETADDR *pAddr); void BanmastersClear(); + void SendToBanmasters(CNetChunk *pP); }; class CNetConsole diff --git a/src/engine/shared/network_server.cpp b/src/engine/shared/network_server.cpp index 32525802..98b88ac5 100644 --- a/src/engine/shared/network_server.cpp +++ b/src/engine/shared/network_server.cpp @@ -8,11 +8,15 @@ #include "netban.h" #include "network.h" +CNetServer::CNetServer() +{ + mem_zero(this, sizeof(*this)); +} bool CNetServer::Open(NETADDR BindAddr, CNetBan *pNetBan, int MaxClients, int MaxClientsPerIP, int Flags) { // zero out the whole structure - mem_zero(this, sizeof(*this)); + //mem_zero(this, sizeof(*this)); // open socket m_Socket = net_udp_create(BindAddr); @@ -271,13 +275,20 @@ int CNetServer::BanmasterAdd(const char *pAddrStr) { if(m_NumBanmasters >= MAX_BANMASTERS) return 2; - - if(net_host_lookup(pAddrStr, &m_aBanmasters[m_NumBanmasters], NETTYPE_IPV4)) + + NETADDR Addr; + if(net_host_lookup(pAddrStr, &Addr, NETTYPE_ALL)) return 1; - - if(m_aBanmasters[m_NumBanmasters].port == 0) - m_aBanmasters[m_NumBanmasters].port = BANMASTER_PORT; - + + if(Addr.port == 0) + Addr.port = BANMASTER_PORT; + + for(int i = 0; i < m_NumBanmasters; i++) + if(mem_comp(&Addr, &m_aBanmasters[i], sizeof(NETADDR)) == 0) + return 3; + + m_aBanmasters[m_NumBanmasters] = Addr; + m_NumBanmasters++; return 0; } @@ -309,3 +320,11 @@ void CNetServer::BanmastersClear() m_NumBanmasters = 0; } +void CNetServer::SendToBanmasters(CNetChunk *pP) +{ + for(int i = 0; i < m_NumBanmasters; i++) + { + pP->m_Address = m_aBanmasters[i]; + Send(pP); + } +} -- cgit 1.4.1 From 977683d4f8f82633ba9ba6a26607b5451bd0c592 Mon Sep 17 00:00:00 2001 From: Teetime Date: Wed, 13 Jun 2012 03:23:03 +0200 Subject: some changes... --- .gitignore | 1 + .project | 79 ++++++++++++++++++++++++++++++++++++ bans.cfg | 1 - src/banmaster/banmaster.cpp | 41 +++++++++++-------- src/banmaster/banmaster.h | 1 - src/base/system.c | 2 + src/base/system.h | 3 ++ src/engine/server/server.cpp | 42 +++++++++---------- src/engine/shared/network.h | 38 ++++++++++------- src/engine/shared/network_server.cpp | 57 ++++++++++++++++---------- 10 files changed, 186 insertions(+), 79 deletions(-) create mode 100644 .project diff --git a/.gitignore b/.gitignore index edbb7eab..e154e323 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ teeworlds* teeworlds_srv* tileset_border* versionsrv* +banmaster* diff --git a/.project b/.project new file mode 100644 index 00000000..12f40087 --- /dev/null +++ b/.project @@ -0,0 +1,79 @@ + + + teeworlds + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.autoBuildTarget + all + + + org.eclipse.cdt.make.core.buildArguments + + + + org.eclipse.cdt.make.core.buildCommand + E:\Dev\git\teeworlds\zcatch_srv_debug.bat + + + org.eclipse.cdt.make.core.cleanBuildTarget + clean + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + false + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.fullBuildTarget + all + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + false + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/bans.cfg b/bans.cfg index bc3e1d65..a32469c6 100644 --- a/bans.cfg +++ b/bans.cfg @@ -1,2 +1 @@ unban_all -bind 127.0.0.1:8302 diff --git a/src/banmaster/banmaster.cpp b/src/banmaster/banmaster.cpp index 97eb2aee..a8a5ad02 100644 --- a/src/banmaster/banmaster.cpp +++ b/src/banmaster/banmaster.cpp @@ -97,15 +97,9 @@ void CleanUp() delete m_pStorage; } -int SendResponse(NETADDR *pAddr, NETADDR *pCheck) +int SendResponse(NETADDR *pAddr, NETADDR *pCheck, const char *pToken) { - static char aIpBan[sizeof(BANMASTER_IPBAN) + NETADDR_MAXSTRSIZE] = { 0 }; - static char *pIpBanContent = aIpBan + sizeof(BANMASTER_IPBAN); - - if (!aIpBan[0]) - mem_copy(aIpBan, BANMASTER_IPBAN, sizeof(BANMASTER_IPBAN)); - - static CNetChunk p; + CNetChunk p; p.m_ClientID = -1; p.m_Address = *pAddr; @@ -116,13 +110,20 @@ int SendResponse(NETADDR *pAddr, NETADDR *pCheck) if(m_NetBan.GetBanInfo(pCheck, aReason, sizeof(aReason), &Expires)) { - net_addr_str(pCheck, pIpBanContent, NETADDR_MAXSTRSIZE, false); - char *pIpBanReason = pIpBanContent + (str_length(pIpBanContent) + 1); - str_copy(pIpBanReason, aReason, 256); + char aCheckAddr[NETADDR_MAXSTRSIZE]; + net_addr_str(pCheck, aCheckAddr, NETADDR_MAXSTRSIZE, false); + + CPacker P; + P.Reset(); + P.AddRaw(BANMASTER_IPBAN, sizeof(BANMASTER_IPBAN)); + P.AddString(aCheckAddr, -1); + P.AddString(aReason, -1); + P.AddString(pToken, -1); - p.m_pData = aIpBan; - p.m_DataSize = sizeof(BANMASTER_IPBAN) + str_length(pIpBanContent) + 1 + str_length(pIpBanReason) + 1; - m_Net.Send(&p); + p.m_pData = P.Data(); + p.m_DataSize = P.Size(); + if(!P.Error()) + m_Net.Send(&p); return 1; } @@ -141,7 +142,7 @@ void AddRecvBan(NETADDR *pFromAddr, unsigned char *pData, int Size) pReason = Up.GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES); NETADDR ReportAddr; - if(net_addr_from_str(&ReportAddr, pIP) == 0 && pName[0] && pReason[0]) + if(!Up.Error() && net_addr_from_str(&ReportAddr, pIP) == 0 && pName[0] && pReason[0]) { for(int i = MAX_BAN_ENTRIES-1; i > 0; i--) mem_copy(&m_RecvBans[i], &m_RecvBans[i-1], sizeof(m_RecvBans[i])); @@ -287,9 +288,13 @@ int main(int argc, const char **argv) // ignore_convention if(Packet.m_DataSize >= (int)sizeof(BANMASTER_IPCHECK) && mem_comp(Packet.m_pData, BANMASTER_IPCHECK, sizeof(BANMASTER_IPCHECK)) == 0) { - char *pAddr = (char *)Packet.m_pData + sizeof(BANMASTER_IPCHECK); + CUnpacker Up; + Up.Reset((unsigned char*) Packet.m_pData + sizeof(BANMASTER_IPCHECK), Packet.m_DataSize - sizeof(BANMASTER_IPCHECK)); + const char *pAddr = Up.GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES); + const char *pToken = Up.GetString(CUnpacker::SANITIZE_CC); + NETADDR CheckAddr; - if(net_addr_from_str(&CheckAddr, pAddr)) + if(net_addr_from_str(&CheckAddr, pAddr) || Up.Error()) { char aBuf[128]; str_format(aBuf, sizeof(aBuf), "dropped weird message, ip='%s' checkaddr='%s'", aAddressStr, pAddr); @@ -299,7 +304,7 @@ int main(int argc, const char **argv) // ignore_convention { CheckAddr.port = 0; - int Banned = SendResponse(&Packet.m_Address, &CheckAddr); + int Banned = SendResponse(&Packet.m_Address, &CheckAddr, pToken); char aIP[NETADDR_MAXSTRSIZE]; char aBuf[256]; diff --git a/src/banmaster/banmaster.h b/src/banmaster/banmaster.h index 296dc14d..fb89e3c0 100644 --- a/src/banmaster/banmaster.h +++ b/src/banmaster/banmaster.h @@ -5,7 +5,6 @@ static const int BANMASTER_PORT = 8302; -//static const char BANMASTER_IPOK[] = {255, 255, 255, 255, 'i', 'p', 'o', 'k'}; static const char BANMASTER_IPBAN[] = {255, 255, 255, 255, 'i', 'p', 'b', 'a'}; static const char BANMASTER_IPCHECK[] = {255, 255, 255, 255, 'i', 'p', 'c', 'h'}; static const char BANMASTER_IPREPORT[] = {255, 255, 255, 255, 'i', 'p', 'r', 'e'}; diff --git a/src/base/system.c b/src/base/system.c index ed0f41ec..99fd0380 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -1820,6 +1820,8 @@ char str_uppercase(char c) int str_toint(const char *str) { return atoi(str); } float str_tofloat(const char *str) { return atof(str); } +void init_rand() { srand(time(NULL)); } +int irand() { return rand(); } static int str_utf8_isstart(char c) diff --git a/src/base/system.h b/src/base/system.h index b3588dbf..bc4ee734 100644 --- a/src/base/system.h +++ b/src/base/system.h @@ -1194,6 +1194,9 @@ int str_isspace(char c); char str_uppercase(char c); unsigned str_quickhash(const char *str); +void init_rand(); +int irand(); + /* Function: gui_messagebox Display plain OS-dependent message box diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index cd73c5a7..3a652d68 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -300,7 +300,7 @@ void CServerBan::ConBanExt(IConsole::IResult *pResult, void *pUser) Packet.m_Flags = NETSENDFLAG_CONNLESS; Packet.m_pData = P.Data(); Packet.m_DataSize = P.Size(); - pThis->Server()->m_NetServer.SendToBanmasters(&Packet); + pThis->Server()->m_NetServer.m_Banmaster.SendToAll(&Packet); pThis->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "banmaster", "Reported ban to banmasters"); } } @@ -1221,38 +1221,34 @@ void CServer::PumpNetwork() { SendServerInfo(&Packet.m_Address, ((unsigned char *)Packet.m_pData)[sizeof(SERVERBROWSE_GETINFO)]); } - - /*if(Packet.m_DataSize >= sizeof(BANMASTER_IPOK) && - mem_comp(Packet.m_pData, BANMASTER_IPOK, sizeof(BANMASTER_IPOK)) == 0 && - m_NetServer.BanmasterCheck(&Packet.m_Address) != -1) - { - }*/ - - if(Packet.m_DataSize >= sizeof(BANMASTER_IPBAN) && + else if(Packet.m_DataSize >= sizeof(BANMASTER_IPBAN) && mem_comp(Packet.m_pData, BANMASTER_IPBAN, sizeof(BANMASTER_IPBAN)) == 0) { if(!g_Config.m_SvGlobalBantime) return; - if(m_NetServer.BanmasterCheck(&Packet.m_Address) == -1) + //Unpack packet + CUnpacker Up; + const char *pIP, *pReason, *pToken; + Up.Reset((unsigned char*)Packet.m_pData + sizeof(BANMASTER_IPBAN), Packet.m_DataSize - sizeof(BANMASTER_IPBAN)); + pIP = Up.GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES); + pReason = Up.GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES); + pToken = Up.GetString(CUnpacker::SANITIZE_CC); + + //check if it's a valid packet + if(Up.Error() || m_NetServer.m_Banmaster.CheckValidity(&Packet.m_Address, pToken) == -1) return; - CUnpacker Up; - char aIp[NETADDR_MAXSTRSIZE]; - char aReason[256]; NETADDR Addr; - Up.Reset((unsigned char*)Packet.m_pData + sizeof(BANMASTER_IPBAN), Packet.m_DataSize - sizeof(BANMASTER_IPBAN)); - str_copy(aIp, Up.GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES), sizeof(aIp)); - str_copy(aReason, Up.GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES), sizeof(aReason)); - if(net_addr_from_str(&Addr, aIp)) + if(net_addr_from_str(&Addr, pIP)) { Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "globalbans", "dropped weird message from banmaster"); return; } - m_ServerBan.BanAddr(&Addr, g_Config.m_SvGlobalBantime * 60, aReason); + m_ServerBan.BanAddr(&Addr, g_Config.m_SvGlobalBantime * 60, pReason); char aBuf[256]; - str_format(aBuf, sizeof(aBuf), "added ban, ip=%s, reason='%s'", aIp, aReason); + str_format(aBuf, sizeof(aBuf), "added ban, ip=%s, reason='%s'", pIP, pReason); Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "globalbans", aBuf); } } @@ -1615,7 +1611,7 @@ void CServer::ConAddBanmaster(IConsole::IResult *pResult, void *pUser) { CServer *pServer = (CServer *)pUser; - int Result = pServer->m_NetServer.BanmasterAdd(pResult->GetString(0)); + int Result = pServer->m_NetServer.m_Banmaster.Add(pResult->GetString(0)); if(Result == 0) pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server/banmaster", "succesfully added banmaster"); @@ -1630,14 +1626,14 @@ void CServer::ConAddBanmaster(IConsole::IResult *pResult, void *pUser) void CServer::ConBanmasters(IConsole::IResult *pResult, void *pUser) { CServer *pServer = (CServer *)pUser; - int NumBanmasters = pServer->m_NetServer.BanmasterNum(); + int NumBanmasters = pServer->m_NetServer.m_Banmaster.Num(); char aBuf[128]; char aIpString[64]; for(int i = 0; i < NumBanmasters; i++) { - NETADDR *pBanmaster = pServer->m_NetServer.BanmasterGet(i); + NETADDR *pBanmaster = pServer->m_NetServer.m_Banmaster.Get(i); net_addr_str(pBanmaster, aIpString, sizeof(aIpString), 0); str_format(aBuf, sizeof(aBuf), "%d: %s", i, aIpString); pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server/banmaster", aBuf); @@ -1648,7 +1644,7 @@ void CServer::ConClearBanmasters(IConsole::IResult *pResult, void *pUser) { CServer *pServer = (CServer *)pUser; - pServer->m_NetServer.BanmastersClear(); + pServer->m_NetServer.m_Banmaster.Clear(); pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server/banmaster", "cleared banmaster list"); } diff --git a/src/engine/shared/network.h b/src/engine/shared/network.h index ea5ed98f..d4418097 100644 --- a/src/engine/shared/network.h +++ b/src/engine/shared/network.h @@ -243,11 +243,6 @@ public: class CNetServer { public: - enum - { - MAX_BANMASTERS=16 - }; - struct CSlot { public: @@ -260,9 +255,6 @@ public: int m_MaxClients; int m_MaxClientsPerIP; - NETADDR m_aBanmasters[MAX_BANMASTERS]; - int m_NumBanmasters; - NETFUNC_NEWCLIENT m_pfnNewClient; NETFUNC_DELCLIENT m_pfnDelClient; void *m_UserPtr; @@ -295,13 +287,29 @@ public: // void SetMaxClientsPerIP(int Max); - // - int BanmasterAdd(const char *pAddrStr); - int BanmasterNum() const; - NETADDR* BanmasterGet(int Index); - int BanmasterCheck(NETADDR *pAddr); - void BanmastersClear(); - void SendToBanmasters(CNetChunk *pP); + class CBanmaster + { + public: + enum + { + MAX_BANMASTERS = 16, + MAX_TOKEN_LENGTH = 16, + }; + + CNetServer *m_pNet; + NETADDR m_aBanmasters[MAX_BANMASTERS]; + char m_aBanmasterToken[MAX_TOKEN_LENGTH]; + int m_NumBanmasters; + + int Add(const char *pAddrStr); + int Num() const; + NETADDR* Get(int Index); + int CheckValidity(NETADDR *pAddr, const char* pToken); + void Clear(); + void SendToAll(CNetChunk *pP); + void GenerateToken(); + }; + CBanmaster m_Banmaster; }; class CNetConsole diff --git a/src/engine/shared/network_server.cpp b/src/engine/shared/network_server.cpp index 98b88ac5..6818c0f0 100644 --- a/src/engine/shared/network_server.cpp +++ b/src/engine/shared/network_server.cpp @@ -4,6 +4,7 @@ #include #include +#include #include "netban.h" #include "network.h" @@ -11,6 +12,9 @@ CNetServer::CNetServer() { mem_zero(this, sizeof(*this)); + init_rand(); + m_Banmaster.m_pNet = this; + m_Banmaster.GenerateToken(); } bool CNetServer::Open(NETADDR BindAddr, CNetBan *pNetBan, int MaxClients, int MaxClientsPerIP, int Flags) @@ -145,21 +149,21 @@ int CNetServer::Recv(CNetChunk *pChunk) // client that wants to connect if(!Found) { - CNetChunk Packet; - char aBuffer[sizeof(BANMASTER_IPCHECK) + NETADDR_MAXSTRSIZE]; - mem_copy(aBuffer, BANMASTER_IPCHECK, sizeof(BANMASTER_IPCHECK)); - net_addr_str(&Addr, aBuffer + sizeof(BANMASTER_IPCHECK), sizeof(aBuffer) - sizeof(BANMASTER_IPCHECK), 0); + char aIP[NETADDR_MAXSTRSIZE]; + net_addr_str(&Addr, aIP, sizeof(aIP), 0); + CPacker P; + P.Reset(); + P.AddRaw(BANMASTER_IPCHECK, sizeof(BANMASTER_IPCHECK)); + P.AddString(aIP, NETADDR_MAXSTRSIZE); + P.AddString(m_Banmaster.m_aBanmasterToken, CBanmaster::MAX_TOKEN_LENGTH); + CNetChunk Packet; Packet.m_ClientID = -1; Packet.m_Flags = NETSENDFLAG_CONNLESS; - Packet.m_DataSize = str_length(aBuffer) + 1; - Packet.m_pData = aBuffer; + Packet.m_DataSize = P.Size(); + Packet.m_pData = P.Data(); - for(int i = 0; i < m_NumBanmasters; i++) - { - Packet.m_Address = m_aBanmasters[i]; - Send(&Packet); - } + m_Banmaster.SendToAll(&Packet); // only allow a specific number of players with the same ip NETADDR ThisAddr = Addr, OtherAddr; @@ -271,7 +275,7 @@ void CNetServer::SetMaxClientsPerIP(int Max) m_MaxClientsPerIP = Max; } -int CNetServer::BanmasterAdd(const char *pAddrStr) +int CNetServer::CBanmaster::Add(const char *pAddrStr) { if(m_NumBanmasters >= MAX_BANMASTERS) return 2; @@ -293,12 +297,12 @@ int CNetServer::BanmasterAdd(const char *pAddrStr) return 0; } -int CNetServer::BanmasterNum() const +int CNetServer::CBanmaster::Num() const { return m_NumBanmasters; } -NETADDR* CNetServer::BanmasterGet(int Index) +NETADDR *CNetServer::CBanmaster::Get(int Index) { if(Index < 0 || Index >= m_NumBanmasters) return 0; @@ -306,25 +310,36 @@ NETADDR* CNetServer::BanmasterGet(int Index) return &m_aBanmasters[Index]; } -int CNetServer::BanmasterCheck(NETADDR *pAddr) +int CNetServer::CBanmaster::CheckValidity(NETADDR *pAddr, const char* pToken) { - for(int i = 0; i < m_NumBanmasters; i++) - if(net_addr_comp(&m_aBanmasters[i], pAddr) == 0) - return i; + if(str_comp(m_aBanmasterToken, pToken) == 0) + for(int i = 0; i < m_NumBanmasters; i++) + if(net_addr_comp(&m_aBanmasters[i], pAddr) == 0) + return i; return -1; } -void CNetServer::BanmastersClear() +void CNetServer::CBanmaster::Clear() { m_NumBanmasters = 0; } -void CNetServer::SendToBanmasters(CNetChunk *pP) +void CNetServer::CBanmaster::SendToAll(CNetChunk *pP) { for(int i = 0; i < m_NumBanmasters; i++) { pP->m_Address = m_aBanmasters[i]; - Send(pP); + m_pNet->Send(pP); + } +} + +void CNetServer::CBanmaster::GenerateToken() +{ + for(int i = 0; i < MAX_TOKEN_LENGTH-1; i++) + { + // 32 - 128 + m_aBanmasterToken[i] = irand() % 97 + 32; } + m_aBanmasterToken[MAX_TOKEN_LENGTH-1] = 0; } -- cgit 1.4.1