/*
* PtokaX - hub server for Direct Connect peer to peer network.
* Copyright (C) 2004-2022 Petr Kozelka, PPK at PtokaX dot org
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3
* as published by the Free Software Foundation.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
#include "stdinc.h"
//---------------------------------------------------------------------------
#include "hashBanManager.h"
//---------------------------------------------------------------------------
#include "PXBReader.h"
#include "ServerManager.h"
#include "SettingManager.h"
#include "UdpDebug.h"
#include "User.h"
#include "utility.h"
#include "tinyxml.h"
//---------------------------------------------------------------------------
#ifdef _BUILD_GUI
#include "../gui.win/BansDialog.h"
#include "../gui.win/RangeBansDialog.h"
#endif
//---------------------------------------------------------------------------
BanManager * BanManager::m_Ptr = nullptr;
//---------------------------------------------------------------------------
static const char sPtokaXBans[] = "PtokaX Bans";
static const size_t szPtokaXBansLen = sizeof(sPtokaXBans) - 1;
static const char sPtokaXRangeBans[] = "PtokaX RangeBans";
static const size_t szPtokaXRangeBansLen = sizeof(sPtokaXRangeBans) - 1;
static const char sBanIds[] = "BT" "NI" "NB" "IP" "IB" "FB" "RE" "BY" "EX";
static const size_t szBanIdsLen = sizeof(sBanIds) - 1;
static const char sRangeBanIds[] = "BT" "RF" "RT" "FB" "RE" "BY" "EX";
static const size_t szRangeBanIdsLen = sizeof(sRangeBanIds) - 1;
//---------------------------------------------------------------------------
BanItemBase::~BanItemBase()
{
free(m_sReason);
free(m_sBy);
}
BanItem::BanItem(void) : m_sNick(NULL), m_pPrev(NULL), m_pNext(NULL), m_pHashNickTablePrev(NULL), m_pHashNickTableNext(NULL), m_pHashIpTablePrev(NULL), m_pHashIpTableNext(NULL), m_ui32NickHash(0)
{
memset(m_ui128IpHash, 0, 16);
memset(m_sIp, 0, sizeof(m_sIp));
}
//---------------------------------------------------------------------------
BanItem::~BanItem(void)
{
free(m_sNick);
}
//---------------------------------------------------------------------------
void BanItem::initIP(const char* pIP)
{
strcpy(m_sIp, pIP);
}
//---------------------------------------------------------------------------
void BanItem::initIP(const User* u)
{
strcpy(m_sIp, u->m_sIP);
memcpy(m_ui128IpHash, u->m_ui128IpHash, sizeof(m_ui128IpHash));
}
//---------------------------------------------------------------------------
RangeBanItem::RangeBanItem(void) : m_pPrev(NULL), m_pNext(NULL)
{
memset(m_sIpFrom, 0, sizeof(m_sIpFrom));
memset(m_sIpTo, 0, sizeof(m_sIpTo));
}
//---------------------------------------------------------------------------
RangeBanItem::~RangeBanItem(void)
{
}
//---------------------------------------------------------------------------
BanManager::BanManager(void) : m_ui32SaveCalled(0), m_pTempBanListS(NULL), m_pTempBanListE(NULL), m_pPermBanListS(NULL), m_pPermBanListE(NULL),
m_pRangeBanListS(NULL), m_pRangeBanListE(NULL)
{
memset(m_pNickBanTable, 0, sizeof(m_pNickBanTable));
memset(m_pIpBanTable, 0, sizeof(m_pIpBanTable));
}
//---------------------------------------------------------------------------
BanManager::~BanManager(void)
{
BanItem * curBan = NULL,
* nextBan = m_pPermBanListS;
while (nextBan != NULL)
{
curBan = nextBan;
nextBan = curBan->m_pNext;
delete curBan;
}
nextBan = m_pTempBanListS;
while (nextBan != NULL)
{
curBan = nextBan;
nextBan = curBan->m_pNext;
delete curBan;
}
RangeBanItem * curRangeBan = NULL,
* nextRangeBan = m_pRangeBanListS;
while (nextRangeBan != NULL)
{
curRangeBan = nextRangeBan;
nextRangeBan = curRangeBan->m_pNext;
delete curRangeBan;
}
IpTableItem * cur = NULL, * next = nullptr;
for (uint32_t ui32i = 0; ui32i < IP_BAN_HASH_TABLE_SIZE; ui32i++)
{
next = m_pIpBanTable[ui32i];
while (next != NULL)
{
cur = next;
next = cur->m_pNext;
delete cur;
}
}
}
//---------------------------------------------------------------------------
bool BanManager::Add(BanItem * pBan)
{
if (Add2Table(pBan) == false)
{
return false;
}
if (((pBan->m_ui8Bits & PERM) == PERM) == true)
{
if (m_pPermBanListE == NULL)
{
m_pPermBanListS = pBan;
m_pPermBanListE = pBan;
}
else
{
m_pPermBanListE->m_pNext = pBan;
pBan->m_pPrev = m_pPermBanListE;
m_pPermBanListE = pBan;
}
}
else
{
if (m_pTempBanListE == NULL)
{
m_pTempBanListS = pBan;
m_pTempBanListE = pBan;
}
else
{
m_pTempBanListE->m_pNext = pBan;
pBan->m_pPrev = m_pTempBanListE;
m_pTempBanListE = pBan;
}
}
#ifdef _BUILD_GUI
if (BansDialog::m_Ptr != NULL)
{
BansDialog::m_Ptr->AddBan(pBan);
}
#endif
return true;
}
//---------------------------------------------------------------------------
bool BanManager::Add2Table(BanItem * pBan)
{
if (((pBan->m_ui8Bits & IP) == IP) == true)
{
if (Add2IpTable(pBan) == false)
{
return false;
}
}
if (((pBan->m_ui8Bits & NICK) == NICK) == true)
{
Add2NickTable(pBan);
}
return true;
}
//---------------------------------------------------------------------------
void BanManager::Add2NickTable(BanItem *Ban)
{
const uint16_t ui16dx = CalcHash(Ban->m_ui32NickHash);
if (m_pNickBanTable[ui16dx] != NULL)
{
m_pNickBanTable[ui16dx]->m_pHashNickTablePrev = Ban;
Ban->m_pHashNickTableNext = m_pNickBanTable[ui16dx];
}
m_pNickBanTable[ui16dx] = Ban;
}
//---------------------------------------------------------------------------
bool BanManager::Add2IpTable(BanItem *Ban)
{
uint16_t ui16IpTableIdx = 0;
if (IN6_IS_ADDR_V4MAPPED((const in6_addr *)Ban->m_ui128IpHash))
{
ui16IpTableIdx = Ban->m_ui128IpHash[14] * Ban->m_ui128IpHash[15];
}
else
{
ui16IpTableIdx = GetIpTableIdx(Ban->m_ui128IpHash);
}
if (m_pIpBanTable[ui16IpTableIdx] == NULL)
{
m_pIpBanTable[ui16IpTableIdx] = new (std::nothrow) IpTableItem();
if (m_pIpBanTable[ui16IpTableIdx] == NULL)
{
AppendDebugLog("%s - [MEM] Cannot allocate IpTableItem in BanManager::Add2IpTable\n");
return false;
}
m_pIpBanTable[ui16IpTableIdx]->m_pNext = nullptr;
m_pIpBanTable[ui16IpTableIdx]->m_pPrev = nullptr;
m_pIpBanTable[ui16IpTableIdx]->pFirstBan = Ban;
return true;
}
IpTableItem * cur = NULL,
* next = m_pIpBanTable[ui16IpTableIdx];
while (next != NULL)
{
cur = next;
next = cur->m_pNext;
if (memcmp(cur->pFirstBan->m_ui128IpHash, Ban->m_ui128IpHash, 16) == 0)
{
cur->pFirstBan->m_pHashIpTablePrev = Ban;
Ban->m_pHashIpTableNext = cur->pFirstBan;
cur->pFirstBan = Ban;
return true;
}
}
cur = new (std::nothrow) IpTableItem;
if (cur == NULL)
{
AppendDebugLog("%s - [MEM] Cannot allocate IpTableBans2 in BanManager::Add2IpTable\n");
return false;
}
cur->pFirstBan = Ban;
cur->m_pNext = m_pIpBanTable[ui16IpTableIdx];
cur->m_pPrev = nullptr;
m_pIpBanTable[ui16IpTableIdx]->m_pPrev = cur;
m_pIpBanTable[ui16IpTableIdx] = cur;
return true;
}
//---------------------------------------------------------------------------
#ifdef _BUILD_GUI
void BanManager::Rem(BanItem * Ban, const bool bFromGui/* = false*/)
{
#else
void BanManager::Rem(BanItem * Ban, const bool /*bFromGui = false*/)
{
#endif
RemFromTable(Ban);
if (((Ban->m_ui8Bits & PERM) == PERM) == true)
{
if (Ban->m_pPrev == NULL)
{
if (Ban->m_pNext == NULL)
{
m_pPermBanListS = nullptr;
m_pPermBanListE = nullptr;
}
else
{
Ban->m_pNext->m_pPrev = nullptr;
m_pPermBanListS = Ban->m_pNext;
}
}
else if (Ban->m_pNext == NULL)
{
Ban->m_pPrev->m_pNext = nullptr;
m_pPermBanListE = Ban->m_pPrev;
}
else
{
Ban->m_pPrev->m_pNext = Ban->m_pNext;
Ban->m_pNext->m_pPrev = Ban->m_pPrev;
}
}
else
{
if (Ban->m_pPrev == NULL)
{
if (Ban->m_pNext == NULL)
{
m_pTempBanListS = nullptr;
m_pTempBanListE = nullptr;
}
else
{
Ban->m_pNext->m_pPrev = nullptr;
m_pTempBanListS = Ban->m_pNext;
}
}
else if (Ban->m_pNext == NULL)
{
Ban->m_pPrev->m_pNext = nullptr;
m_pTempBanListE = Ban->m_pPrev;
}
else
{
Ban->m_pPrev->m_pNext = Ban->m_pNext;
Ban->m_pNext->m_pPrev = Ban->m_pPrev;
}
}
#ifdef _BUILD_GUI
if (bFromGui == false && BansDialog::m_Ptr != NULL)
{
BansDialog::m_Ptr->RemoveBan(Ban);
}
#endif
}
//---------------------------------------------------------------------------
void BanManager::RemFromTable(BanItem *Ban)
{
if (((Ban->m_ui8Bits & IP) == IP) == true)
{
RemFromIpTable(Ban);
}
if (((Ban->m_ui8Bits & NICK) == NICK) == true)
{
RemFromNickTable(Ban);
}
}
//---------------------------------------------------------------------------
void BanManager::RemFromNickTable(BanItem *Ban)
{
if (Ban->m_pHashNickTablePrev == NULL)
{
const uint16_t ui16dx = CalcHash(Ban->m_ui32NickHash);
if (Ban->m_pHashNickTableNext == NULL)
{
m_pNickBanTable[ui16dx] = nullptr;
}
else
{
Ban->m_pHashNickTableNext->m_pHashNickTablePrev = nullptr;
m_pNickBanTable[ui16dx] = Ban->m_pHashNickTableNext;
}
}
else if (Ban->m_pHashNickTableNext == NULL)
{
Ban->m_pHashNickTablePrev->m_pHashNickTableNext = nullptr;
}
else
{
Ban->m_pHashNickTablePrev->m_pHashNickTableNext = Ban->m_pHashNickTableNext;
Ban->m_pHashNickTableNext->m_pHashNickTablePrev = Ban->m_pHashNickTablePrev;
}
Ban->m_pHashNickTablePrev = nullptr;
Ban->m_pHashNickTableNext = nullptr;
}
//---------------------------------------------------------------------------
void BanManager::RemFromIpTable(BanItem *Ban)
{
uint16_t ui16IpTableIdx = 0;
if (IN6_IS_ADDR_V4MAPPED((const in6_addr *)Ban->m_ui128IpHash))
{
ui16IpTableIdx = Ban->m_ui128IpHash[14] * Ban->m_ui128IpHash[15];
}
else
{
ui16IpTableIdx = GetIpTableIdx(Ban->m_ui128IpHash);
}
if (Ban->m_pHashIpTablePrev == NULL)
{
IpTableItem * cur = NULL,
* next = m_pIpBanTable[ui16IpTableIdx];
while (next != NULL)
{
cur = next;
next = cur->m_pNext;
if (memcmp(cur->pFirstBan->m_ui128IpHash, Ban->m_ui128IpHash, 16) == 0)
{
if (Ban->m_pHashIpTableNext == NULL)
{
if (cur->m_pPrev == NULL)
{
if (cur->m_pNext == NULL)
{
m_pIpBanTable[ui16IpTableIdx] = nullptr;
}
else
{
cur->m_pNext->m_pPrev = nullptr;
m_pIpBanTable[ui16IpTableIdx] = cur->m_pNext;
}
}
else if (cur->m_pNext == NULL)
{
cur->m_pPrev->m_pNext = nullptr;
}
else
{
cur->m_pPrev->m_pNext = cur->m_pNext;
cur->m_pNext->m_pPrev = cur->m_pPrev;
}
delete cur;
}
else
{
Ban->m_pHashIpTableNext->m_pHashIpTablePrev = nullptr;
cur->pFirstBan = Ban->m_pHashIpTableNext;
}
break;
}
}
}
else if (Ban->m_pHashIpTableNext == NULL)
{
Ban->m_pHashIpTablePrev->m_pHashIpTableNext = nullptr;
}
else
{
Ban->m_pHashIpTablePrev->m_pHashIpTableNext = Ban->m_pHashIpTableNext;
Ban->m_pHashIpTableNext->m_pHashIpTablePrev = Ban->m_pHashIpTablePrev;
}
Ban->m_pHashIpTablePrev = nullptr;
Ban->m_pHashIpTableNext = nullptr;
}
//---------------------------------------------------------------------------
BanItem* BanManager::Find(BanItem *Ban)
{
if (m_pTempBanListS != NULL)
{
time_t acc_time;
time(&acc_time);
BanItem * curBan = NULL,
* nextBan = m_pTempBanListS;
while (nextBan != NULL)
{
curBan = nextBan;
nextBan = curBan->m_pNext;
if (acc_time > curBan->m_tTempBanExpire)
{
Rem(curBan);
delete curBan;
continue;
}
if (curBan == Ban)
{
return curBan;
}
}
}
if (m_pPermBanListS != NULL)
{
BanItem * curBan = NULL,
* nextBan = m_pPermBanListS;
while (nextBan != NULL)
{
curBan = nextBan;
nextBan = curBan->m_pNext;
if (curBan == Ban)
{
return curBan;
}
}
}
return NULL;
}
//---------------------------------------------------------------------------
void BanManager::Remove(BanItem *Ban)
{
if (m_pTempBanListS != NULL)
{
time_t acc_time;
time(&acc_time);
BanItem * curBan = NULL,
* nextBan = m_pTempBanListS;
while (nextBan != NULL)
{
curBan = nextBan;
nextBan = curBan->m_pNext;
if (acc_time > curBan->m_tTempBanExpire)
{
Rem(curBan);
delete curBan;
continue;
}
if (curBan == Ban)
{
Rem(Ban);
delete Ban;
return;
}
}
}
if (m_pPermBanListS != NULL)
{
BanItem * curBan = NULL,
* nextBan = m_pPermBanListS;
while (nextBan != NULL)
{
curBan = nextBan;
nextBan = curBan->m_pNext;
if (curBan == Ban)
{
Rem(Ban);
delete Ban;
return;
}
}
}
}
//---------------------------------------------------------------------------
void BanManager::AddRange(RangeBanItem *RangeBan)
{
if (m_pRangeBanListE == NULL)
{
m_pRangeBanListS = RangeBan;
m_pRangeBanListE = RangeBan;
}
else
{
m_pRangeBanListE->m_pNext = RangeBan;
RangeBan->m_pPrev = m_pRangeBanListE;
m_pRangeBanListE = RangeBan;
}
#ifdef _BUILD_GUI
if (RangeBansDialog::m_Ptr != NULL)
{
RangeBansDialog::m_Ptr->AddRangeBan(RangeBan);
}
#endif
}
//---------------------------------------------------------------------------
#ifdef _BUILD_GUI
void BanManager::RemRange(RangeBanItem *RangeBan, const bool bFromGui/* = false*/)
{
#else
void BanManager::RemRange(RangeBanItem *RangeBan, const bool /*bFromGui = false*/)
{
#endif
if (RangeBan->m_pPrev == NULL)
{
if (RangeBan->m_pNext == NULL)
{
m_pRangeBanListS = nullptr;
m_pRangeBanListE = nullptr;
}
else
{
RangeBan->m_pNext->m_pPrev = nullptr;
m_pRangeBanListS = RangeBan->m_pNext;
}
}
else if (RangeBan->m_pNext == NULL)
{
RangeBan->m_pPrev->m_pNext = nullptr;
m_pRangeBanListE = RangeBan->m_pPrev;
}
else
{
RangeBan->m_pPrev->m_pNext = RangeBan->m_pNext;
RangeBan->m_pNext->m_pPrev = RangeBan->m_pPrev;
}
#ifdef _BUILD_GUI
if (bFromGui == false && RangeBansDialog::m_Ptr != NULL)
{
RangeBansDialog::m_Ptr->RemoveRangeBan(RangeBan);
}
#endif
}
//---------------------------------------------------------------------------
RangeBanItem* BanManager::FindRange(RangeBanItem *RangeBan)
{
if (m_pRangeBanListS != NULL)
{
time_t acc_time;
time(&acc_time);
RangeBanItem * curBan = NULL,
* nextBan = m_pRangeBanListS;
while (nextBan != NULL)
{
curBan = nextBan;
nextBan = curBan->m_pNext;
if (((curBan->m_ui8Bits & BanManager::TEMP) == BanManager::TEMP) == true && acc_time > curBan->m_tTempBanExpire)
{
RemRange(curBan);
delete curBan;
continue;
}
if (curBan == RangeBan)
{
return curBan;
}
}
}
return NULL;
}
//---------------------------------------------------------------------------
void BanManager::RemoveRange(RangeBanItem *RangeBan)
{
if (m_pRangeBanListS != NULL)
{
time_t acc_time;
time(&acc_time);
RangeBanItem * curBan = NULL,
* nextBan = m_pRangeBanListS;
while (nextBan != NULL)
{
curBan = nextBan;
nextBan = curBan->m_pNext;
if (((curBan->m_ui8Bits & BanManager::TEMP) == BanManager::TEMP) == true && acc_time > curBan->m_tTempBanExpire)
{
RemRange(curBan);
delete curBan;
continue;
}
if (curBan == RangeBan)
{
RemRange(RangeBan);
delete RangeBan;
return;
}
}
}
}
//---------------------------------------------------------------------------
BanItem* BanManager::FindNick(User* pUser)
{
const uint16_t ui16dx = CalcHash(pUser->m_ui32NickHash);
time_t acc_time;
time(&acc_time);
BanItem * cur = NULL,
* next = m_pNickBanTable[ui16dx];
while (next != NULL)
{
cur = next;
next = cur->m_pHashNickTableNext;
if (cur->m_ui32NickHash == pUser->m_ui32NickHash && strcasecmp(cur->m_sNick, pUser->m_sNick) == 0)
{
// PPK ... check if temban expired
if (((cur->m_ui8Bits & BanManager::TEMP) == BanManager::TEMP) == true)
{
if (acc_time >= cur->m_tTempBanExpire)
{
Rem(cur);
delete cur;
continue;
}
}
return cur;
}
}
return NULL;
}
//---------------------------------------------------------------------------
BanItem* BanManager::FindIP(User* u)
{
time_t acc_time;
time(&acc_time);
IpTableItem * cur = NULL,
* next = m_pIpBanTable[u->m_ui16IpTableIdx];
BanItem * curBan = NULL, * nextBan = nullptr;
while (next != NULL)
{
cur = next;
next = cur->m_pNext;
if (memcmp(cur->pFirstBan->m_ui128IpHash, u->m_ui128IpHash, 16) == 0)
{
nextBan = cur->pFirstBan;
while (nextBan != NULL)
{
curBan = nextBan;
nextBan = curBan->m_pHashIpTableNext;
// PPK ... check if temban expired
if (((curBan->m_ui8Bits & BanManager::TEMP) == BanManager::TEMP) == true)
{
if (acc_time >= curBan->m_tTempBanExpire)
{
Rem(curBan);
delete curBan;
continue;
}
}
return curBan;
}
}
}
return NULL;
}
//---------------------------------------------------------------------------
RangeBanItem* BanManager::FindRange(User* u)
{
time_t acc_time;
time(&acc_time);
RangeBanItem * cur = NULL,
* next = m_pRangeBanListS;
while (next != NULL)
{
cur = next;
next = cur->m_pNext;
if (memcmp(cur->m_ui128FromIpHash, u->m_ui128IpHash, 16) <= 0 && memcmp(cur->m_ui128ToIpHash, u->m_ui128IpHash, 16) >= 0)
{
// PPK ... check if temban expired
if (((cur->m_ui8Bits & TEMP) == TEMP) == true)
{
if (acc_time >= cur->m_tTempBanExpire)
{
RemRange(cur);
delete cur;
continue;
}
}
return cur;
}
}
return NULL;
}
//---------------------------------------------------------------------------
BanItem* BanManager::FindFull(const uint8_t * m_ui128IpHash)
{
time_t acc_time;
time(&acc_time);
return FindFull(m_ui128IpHash, acc_time);
}
//---------------------------------------------------------------------------
BanItem* BanManager::FindFull(const uint8_t * m_ui128IpHash, const time_t &acc_time)
{
uint16_t ui16IpTableIdx = 0;
if (IN6_IS_ADDR_V4MAPPED((const in6_addr *)m_ui128IpHash))
{
ui16IpTableIdx = m_ui128IpHash[14] * m_ui128IpHash[15];
}
else
{
ui16IpTableIdx = GetIpTableIdx(m_ui128IpHash);
}
IpTableItem * cur = NULL,
* next = m_pIpBanTable[ui16IpTableIdx];
BanItem * curBan = NULL, * nextBan = NULL, * fnd = nullptr;
while (next != NULL)
{
cur = next;
next = cur->m_pNext;
if (memcmp(cur->pFirstBan->m_ui128IpHash, m_ui128IpHash, 16) == 0)
{
nextBan = cur->pFirstBan;
while (nextBan != NULL)
{
curBan = nextBan;
nextBan = curBan->m_pHashIpTableNext;
// PPK ... check if temban expired
if (((curBan->m_ui8Bits & BanManager::TEMP) == BanManager::TEMP) == true)
{
if (acc_time >= curBan->m_tTempBanExpire)
{
Rem(curBan);
delete curBan;
continue;
}
}
if (((curBan->m_ui8Bits & BanManager::FULL) == BanManager::FULL) == true)
{
return curBan;
}
else if (fnd == NULL)
{
fnd = curBan;
}
}
}
}
return fnd;
}
//---------------------------------------------------------------------------
RangeBanItem* BanManager::FindFullRange(const uint8_t * m_ui128IpHash, const time_t &acc_time)
{
RangeBanItem * cur = NULL, * fnd = NULL,
* next = m_pRangeBanListS;
while (next != NULL)
{
cur = next;
next = cur->m_pNext;
if (memcmp(cur->m_ui128FromIpHash, m_ui128IpHash, 16) <= 0 && memcmp(cur->m_ui128ToIpHash, m_ui128IpHash, 16) >= 0)
{
// PPK ... check if temban expired
if (((cur->m_ui8Bits & TEMP) == TEMP) == true)
{
if (acc_time >= cur->m_tTempBanExpire)
{
RemRange(cur);
delete cur;
continue;
}
}
if (((cur->m_ui8Bits & FULL) == FULL) == true)
{
return cur;
}
else if (fnd == NULL)
{
fnd = cur;
}
}
}
return fnd;
}
//---------------------------------------------------------------------------
BanItem* BanManager::FindNick(const char * sNick, const size_t szNickLen)
{
uint32_t hash = HashNick(sNick, szNickLen);
time_t acc_time;
time(&acc_time);
return FindNick(hash, acc_time, sNick);
}
//---------------------------------------------------------------------------
BanItem* BanManager::FindNick(const uint32_t ui32Hash, const time_t &acc_time, const char * sNick)
{
const uint16_t ui16dx = CalcHash(ui32Hash);
BanItem * cur = NULL,
* next = m_pNickBanTable[ui16dx];
while (next != NULL)
{
cur = next;
next = cur->m_pHashNickTableNext;
if (cur->m_ui32NickHash == ui32Hash && strcasecmp(cur->m_sNick, sNick) == 0)
{
// PPK ... check if temban expired
if (((cur->m_ui8Bits & BanManager::TEMP) == BanManager::TEMP) == true)
{
if (acc_time >= cur->m_tTempBanExpire)
{
Rem(cur);
delete cur;
continue;
}
}
return cur;
}
}
return NULL;
}
//---------------------------------------------------------------------------
BanItem* BanManager::FindIP(const uint8_t * m_ui128IpHash, const time_t &acc_time)
{
uint16_t ui16IpTableIdx = 0;
if (IN6_IS_ADDR_V4MAPPED((const in6_addr *)m_ui128IpHash))
{
ui16IpTableIdx = m_ui128IpHash[14] * m_ui128IpHash[15];
}
else
{
ui16IpTableIdx = GetIpTableIdx(m_ui128IpHash);
}
IpTableItem * cur = NULL,
* next = m_pIpBanTable[ui16IpTableIdx];
BanItem * curBan = NULL, * nextBan = nullptr;
while (next != NULL)
{
cur = next;
next = cur->m_pNext;
if (memcmp(cur->pFirstBan->m_ui128IpHash, m_ui128IpHash, 16) == 0)
{
nextBan = cur->pFirstBan;
while (nextBan != NULL)
{
curBan = nextBan;
nextBan = curBan->m_pHashIpTableNext;
// PPK ... check if temban expired
if (((curBan->m_ui8Bits & BanManager::TEMP) == BanManager::TEMP) == true)
{
if (acc_time >= curBan->m_tTempBanExpire)
{
Rem(curBan);
delete curBan;
continue;
}
}
return curBan;
}
}
}
return NULL;
}
//---------------------------------------------------------------------------
RangeBanItem* BanManager::FindRange(const uint8_t * m_ui128IpHash, const time_t &acc_time)
{
RangeBanItem * cur = NULL,
* next = m_pRangeBanListS;
while (next != NULL)
{
cur = next;
next = cur->m_pNext;
// PPK ... check if temban expired
if (((cur->m_ui8Bits & TEMP) == TEMP) == true)
{
if (acc_time >= cur->m_tTempBanExpire)
{
RemRange(cur);
delete cur;
continue;
}
}
if (memcmp(cur->m_ui128FromIpHash, m_ui128IpHash, 16) <= 0 && memcmp(cur->m_ui128ToIpHash, m_ui128IpHash, 16) >= 0)
{
return cur;
}
}
return NULL;
}
//---------------------------------------------------------------------------
RangeBanItem* BanManager::FindRange(const uint8_t * ui128FromHash, const uint8_t * ui128ToHash, const time_t &acc_time)
{
RangeBanItem * cur = NULL,
* next = m_pRangeBanListS;
while (next != NULL)
{
cur = next;
next = cur->m_pNext;
if (memcmp(cur->m_ui128FromIpHash, ui128FromHash, 16) == 0 && memcmp(cur->m_ui128ToIpHash, ui128ToHash, 16) == 0)
{
// PPK ... check if temban expired
if (((cur->m_ui8Bits & TEMP) == TEMP) == true)
{
if (acc_time >= cur->m_tTempBanExpire)
{
RemRange(cur);
delete cur;
continue;
}
}
return cur;
}
}
return NULL;
}
//---------------------------------------------------------------------------
BanItem* BanManager::FindTempNick(const char * sNick, const size_t szNickLen)
{
uint32_t hash = HashNick(sNick, szNickLen);
time_t acc_time;
time(&acc_time);
return FindTempNick(hash, acc_time, sNick);
}
//---------------------------------------------------------------------------
BanItem* BanManager::FindTempNick(const uint32_t ui32Hash, const time_t &acc_time, const char * sNick)
{
const uint16_t ui16dx = CalcHash(ui32Hash);
BanItem * cur = NULL,
* next = m_pNickBanTable[ui16dx];
while (next != NULL)
{
cur = next;
next = cur->m_pHashNickTableNext;
if (cur->m_ui32NickHash == ui32Hash && strcasecmp(cur->m_sNick, sNick) == 0)
{
// PPK ... check if temban expired
if (((cur->m_ui8Bits & BanManager::TEMP) == BanManager::TEMP) == true)
{
if (acc_time >= cur->m_tTempBanExpire)
{
Rem(cur);
delete cur;
continue;
}
return cur;
}
}
}
return NULL;
}
//---------------------------------------------------------------------------
BanItem* BanManager::FindTempIP(const uint8_t * m_ui128IpHash, const time_t &acc_time)
{
uint16_t ui16IpTableIdx = 0;
if (IN6_IS_ADDR_V4MAPPED((const in6_addr *)m_ui128IpHash))
{
ui16IpTableIdx = m_ui128IpHash[14] * m_ui128IpHash[15];
}
else
{
ui16IpTableIdx = GetIpTableIdx(m_ui128IpHash);
}
IpTableItem * cur = NULL,
* next = m_pIpBanTable[ui16IpTableIdx];
BanItem * curBan = NULL, * nextBan = nullptr;
while (next != NULL)
{
cur = next;
next = cur->m_pNext;
if (memcmp(cur->pFirstBan->m_ui128IpHash, m_ui128IpHash, 16) == 0)
{
nextBan = cur->pFirstBan;
while (nextBan != NULL)
{
curBan = nextBan;
nextBan = curBan->m_pHashIpTableNext;
// PPK ... check if temban expired
if (((curBan->m_ui8Bits & BanManager::TEMP) == BanManager::TEMP) == true)
{
if (acc_time >= curBan->m_tTempBanExpire)
{
Rem(curBan);
delete curBan;
continue;
}
return curBan;
}
}
}
}
return NULL;
}
//---------------------------------------------------------------------------
BanItem* BanManager::FindPermNick(const char * sNick, const size_t szNickLen)
{
uint32_t hash = HashNick(sNick, szNickLen);
return FindPermNick(hash, sNick);
}
//---------------------------------------------------------------------------
BanItem* BanManager::FindPermNick(const uint32_t ui32Hash, const char * sNick)
{
const uint16_t ui16dx = CalcHash(ui32Hash);
BanItem * cur = NULL,
* next = m_pNickBanTable[ui16dx];
while (next != NULL)
{
cur = next;
next = cur->m_pHashNickTableNext;
if (cur->m_ui32NickHash == ui32Hash && strcasecmp(cur->m_sNick, sNick) == 0)
{
if (((cur->m_ui8Bits & BanManager::PERM) == BanManager::PERM) == true)
{
return cur;
}
}
}
return NULL;
}
//---------------------------------------------------------------------------
BanItem* BanManager::FindPermIP(const uint8_t * m_ui128IpHash)
{
uint16_t ui16IpTableIdx = 0;
if (IN6_IS_ADDR_V4MAPPED((const in6_addr *)m_ui128IpHash))
{
ui16IpTableIdx = m_ui128IpHash[14] * m_ui128IpHash[15];
}
else
{
ui16IpTableIdx = GetIpTableIdx(m_ui128IpHash);
}
IpTableItem * cur = NULL,
* next = m_pIpBanTable[ui16IpTableIdx];
BanItem * curBan = NULL, * nextBan = nullptr;
while (next != NULL)
{
cur = next;
next = cur->m_pNext;
if (memcmp(cur->pFirstBan->m_ui128IpHash, m_ui128IpHash, 16) == 0)
{
nextBan = cur->pFirstBan;
while (nextBan != NULL)
{
curBan = nextBan;
nextBan = curBan->m_pHashIpTableNext;
if (((curBan->m_ui8Bits & BanManager::PERM) == BanManager::PERM) == true)
{
return curBan;
}
}
}
}
return NULL;
}
//---------------------------------------------------------------------------
void BanManager::Load()
{
#ifdef _WIN32
if (FileExist((ServerManager::m_sPath + "\\cfg\\Bans.pxb").c_str()) == false)
{
#else
if (FileExist((ServerManager::m_sPath + "/cfg/Bans.pxb").c_str()) == false)
{
#endif
LoadXML();
return;
}
PXBReader pxbBans;
// Open regs file
#ifdef _WIN32
if (pxbBans.OpenFileRead((ServerManager::m_sPath + "\\cfg\\Bans.pxb").c_str(), 9) == false)
{
#else
if (pxbBans.OpenFileRead((ServerManager::m_sPath + "/cfg/Bans.pxb").c_str(), 9) == false)
{
#endif
return;
}
// Read file header
uint16_t ui16Identificators[9];
ui16Identificators[0] = *((uint16_t *)"FI");
ui16Identificators[1] = *((uint16_t *)"FV");
if (pxbBans.ReadNextItem(ui16Identificators, 2) == false)
{
return;
}
// Check header if we have correct file
if (pxbBans.m_ui16ItemLengths[0] != szPtokaXBansLen || strncmp((char *)pxbBans.m_pItemDatas[0], sPtokaXBans, szPtokaXBansLen) != 0)
{
return;
}
{
uint32_t ui32FileVersion = ntohl(*((uint32_t *)(pxbBans.m_pItemDatas[1])));
if (ui32FileVersion < 1)
{
return;
}
}
time_t tmAccTime;
time(&tmAccTime);
// "BT" "NI" "NB" "IP" "IB" "FB" "RE" "BY" "EX"
memcpy(ui16Identificators, sBanIds, szBanIdsLen);
bool bSuccess = pxbBans.ReadNextItem(ui16Identificators, 9);
while (bSuccess == true)
{
BanItem * pBan = new (std::nothrow) BanItem();
if (pBan == NULL)
{
AppendDebugLog("%s - [MEM] Cannot allocate pBan in BanManager::Load\n");
exit(EXIT_FAILURE);
}
// Permanent or temporary ban?
pBan->m_ui8Bits |= (((char *)pxbBans.m_pItemDatas[0])[0] == '0' ? PERM : TEMP);
// Do we have some nick?
if (pxbBans.m_ui16ItemLengths[1] != 0)
{
if (pxbBans.m_ui16ItemLengths[1] > 64)
{
AppendDebugLogFormat("[ERR] sNick too long %hu in BanManager::Load\n", pxbBans.m_ui16ItemLengths[1]);
exit(EXIT_FAILURE);
}
pBan->m_sNick = (char *)malloc(pxbBans.m_ui16ItemLengths[1] + 1);
if (pBan->m_sNick == NULL)
{
AppendDebugLogFormat("[MEM] Cannot allocate %hu bytes for sNick in BanManager::Load\n", pxbBans.m_ui16ItemLengths[1] + 1);
exit(EXIT_FAILURE);
}
memcpy(pBan->m_sNick, pxbBans.m_pItemDatas[1], pxbBans.m_ui16ItemLengths[1]);
pBan->m_sNick[pxbBans.m_ui16ItemLengths[1]] = '\0';
pBan->m_ui32NickHash = HashNick(pBan->m_sNick, pxbBans.m_ui16ItemLengths[1]);
// it is nick ban?
if (((char *)pxbBans.m_pItemDatas[2])[0] != '0')
{
pBan->m_ui8Bits |= NICK;
}
}
// Do we have some IP address?
if (pxbBans.m_ui16ItemLengths[3] != 0 && IN6_IS_ADDR_UNSPECIFIED((const in6_addr *)pxbBans.m_pItemDatas[3]) == 0)
{
if (pxbBans.m_ui16ItemLengths[3] != 16)
{
AppendDebugLogFormat("[ERR] Ban IP address have incorrect length %hu in BanManager::Load\n", pxbBans.m_ui16ItemLengths[3]);
exit(EXIT_FAILURE);
}
memcpy(pBan->m_ui128IpHash, pxbBans.m_pItemDatas[3], 16);
if (IN6_IS_ADDR_V4MAPPED((const in6_addr *)pBan->m_ui128IpHash))
{
in_addr ipv4addr;
memcpy(&ipv4addr, pBan->m_ui128IpHash + 12, 4);
pBan->initIP(inet_ntoa(ipv4addr));
}
else
{
#if defined(_WIN32) && !defined(_WIN64) && !defined(_WIN_IOT)
win_inet_ntop(pBan->m_ui128IpHash, pBan->m_sIp, 40);
#else
inet_ntop(AF_INET6, pBan->m_ui128IpHash, pBan->m_sIp, 40);
#endif
}
// it is IP ban?
if (((char *)pxbBans.m_pItemDatas[4])[0] != '0')
{
pBan->m_ui8Bits |= IP;
}
// it is full ban ?
if (((char *)pxbBans.m_pItemDatas[5])[0] != '0')
{
pBan->m_ui8Bits |= FULL;
}
}
// Do we have reason?
if (pxbBans.m_ui16ItemLengths[6] != 0)
{
if (pxbBans.m_ui16ItemLengths[6] > 511)
{
pxbBans.m_ui16ItemLengths[6] = 511;
}
pBan->m_sReason = (char *)malloc(pxbBans.m_ui16ItemLengths[6] + 1);
if (pBan->m_sReason == NULL)
{
AppendDebugLogFormat("[MEM] Cannot allocate %hu bytes for sReason in BanManager::Load\n", pxbBans.m_ui16ItemLengths[6] + 1);
exit(EXIT_FAILURE);
}
memcpy(pBan->m_sReason, pxbBans.m_pItemDatas[6], pxbBans.m_ui16ItemLengths[6]);
pBan->m_sReason[pxbBans.m_ui16ItemLengths[6]] = '\0';
}
// Do we have who created ban?
if (pxbBans.m_ui16ItemLengths[7] != 0)
{
if (pxbBans.m_ui16ItemLengths[7] > 64)
{
pxbBans.m_ui16ItemLengths[7] = 64;
}
pBan->m_sBy = (char *)malloc(pxbBans.m_ui16ItemLengths[7] + 1);
if (pBan->m_sBy == NULL)
{
AppendDebugLogFormat("[MEM] Cannot allocate %hu bytes for sBy in BanManager::Load\n", pxbBans.m_ui16ItemLengths[7] + 1);
exit(EXIT_FAILURE);
}
memcpy(pBan->m_sBy, pxbBans.m_pItemDatas[7], pxbBans.m_ui16ItemLengths[7]);
pBan->m_sBy[pxbBans.m_ui16ItemLengths[7]] = '\0';
}
// it is temporary ban?
if (((pBan->m_ui8Bits & TEMP) == TEMP) == true)
{
if (pxbBans.m_ui16ItemLengths[8] != 8)
{
AppendDebugLogFormat("[ERR] Temp ban expire time have incorrect length %hu in BanManager::Load\n", pxbBans.m_ui16ItemLengths[8]);
exit(EXIT_FAILURE);
}
else
{
// Temporary ban expiration datetime
pBan->m_tTempBanExpire = (time_t)be64toh(*((uint64_t *)(pxbBans.m_pItemDatas[8])));
if (tmAccTime >= pBan->m_tTempBanExpire)
{
delete pBan;
}
else
{
if (Add(pBan) == false)
{
AppendDebugLog("%s [ERR] Add ban failed in BanManager::Load\n");
exit(EXIT_FAILURE);
}
}
}
}
else
{
if (Add(pBan) == false)
{
AppendDebugLog("%s [ERR] Add2 ban failed in BanManager::Load\n");
exit(EXIT_FAILURE);
}
}
bSuccess = pxbBans.ReadNextItem(ui16Identificators, 9);
}
PXBReader pxbRangeBans;
// Open regs file
#ifdef _WIN32
if (pxbRangeBans.OpenFileRead((ServerManager::m_sPath + "\\cfg\\RangeBans.pxb").c_str(), 7) == false)
{
#else
if (pxbRangeBans.OpenFileRead((ServerManager::m_sPath + "/cfg/RangeBans.pxb").c_str(), 7) == false)
{
#endif
return;
}
// Read file header
ui16Identificators[0] = *((uint16_t *)"FI");
ui16Identificators[1] = *((uint16_t *)"FV");
if (pxbRangeBans.ReadNextItem(ui16Identificators, 2) == false)
{
return;
}
// Check header if we have correct file
if (pxbRangeBans.m_ui16ItemLengths[0] != szPtokaXRangeBansLen || strncmp((char *)pxbRangeBans.m_pItemDatas[0], sPtokaXRangeBans, szPtokaXRangeBansLen) != 0)
{
return;
}
{
uint32_t ui32FileVersion = ntohl(*((uint32_t *)(pxbRangeBans.m_pItemDatas[1])));
if (ui32FileVersion < 1)
{
return;
}
}
// // "BT" "RF" "RT" "FB" "RE" "BY" "EX";
memcpy(ui16Identificators, sRangeBanIds, szRangeBanIdsLen);
bSuccess = pxbRangeBans.ReadNextItem(ui16Identificators, 7);
while (bSuccess == true)
{
RangeBanItem * pRangeBan = new (std::nothrow) RangeBanItem();
if (pRangeBan == NULL)
{
AppendDebugLog("%s - [MEM] Cannot allocate pRangeBan in BanManager::Load\n");
exit(EXIT_FAILURE);
}
// Permanent or temporary ban?
pRangeBan->m_ui8Bits |= (((char *)pxbRangeBans.m_pItemDatas[0])[0] == '0' ? PERM : TEMP);
// Do we have first IP address?
if (pxbRangeBans.m_ui16ItemLengths[1] != 16)
{
AppendDebugLogFormat("[ERR] Range Ban first IP address have incorrect length %hu in BanManager::Load\n", pxbBans.m_ui16ItemLengths[1]);
exit(EXIT_FAILURE);
}
memcpy(pRangeBan->m_ui128FromIpHash, pxbRangeBans.m_pItemDatas[1], 16);
if (IN6_IS_ADDR_V4MAPPED((const in6_addr *)pRangeBan->m_ui128FromIpHash.data()))
{
in_addr ipv4addr;
memcpy(&ipv4addr, pRangeBan->m_ui128FromIpHash + 12, 4);
strcpy(pRangeBan->m_sIpFrom, inet_ntoa(ipv4addr));
}
else
{
#if defined(_WIN32) && !defined(_WIN64) && !defined(_WIN_IOT)
win_inet_ntop(pRangeBan->m_ui128FromIpHash, pRangeBan->m_sIpFrom, 40);
#else
inet_ntop(AF_INET6, pRangeBan->m_ui128FromIpHash, pRangeBan->m_sIpFrom, 40);
#endif
}
// Do we have second IP address?
if (pxbRangeBans.m_ui16ItemLengths[2] != 16)
{
AppendDebugLogFormat("[ERR] Range Ban second IP address have incorrect length %hu in BanManager::Load\n", pxbBans.m_ui16ItemLengths[2]);
exit(EXIT_FAILURE);
}
memcpy(pRangeBan->m_ui128ToIpHash, pxbRangeBans.m_pItemDatas[2], 16);
if (IN6_IS_ADDR_V4MAPPED((const in6_addr *)pRangeBan->m_ui128ToIpHash.data()))
{
in_addr ipv4addr;
memcpy(&ipv4addr, pRangeBan->m_ui128ToIpHash + 12, 4);
strcpy(pRangeBan->m_sIpTo, inet_ntoa(ipv4addr));
}
else
{
#if defined(_WIN32) && !defined(_WIN64) && !defined(_WIN_IOT)
win_inet_ntop(pRangeBan->m_ui128ToIpHash, pRangeBan->m_sIpTo, 40);
#else
inet_ntop(AF_INET6, pRangeBan->m_ui128ToIpHash, pRangeBan->m_sIpTo, 40);
#endif
}
// it is full ban ?
if (((char *)pxbRangeBans.m_pItemDatas[3])[0] != '0')
{
pRangeBan->m_ui8Bits |= FULL;
}
// Do we have reason?
if (pxbRangeBans.m_ui16ItemLengths[4] != 0)
{
if (pxbRangeBans.m_ui16ItemLengths[4] > 511)
{
pxbRangeBans.m_ui16ItemLengths[4] = 511;
}
pRangeBan->m_sReason = (char *)malloc(pxbRangeBans.m_ui16ItemLengths[4] + 1);
if (pRangeBan->m_sReason == NULL)
{
AppendDebugLogFormat("[MEM] Cannot allocate %hu bytes for sReason2 in BanManager::Load\n", pxbRangeBans.m_ui16ItemLengths[4] + 1);
exit(EXIT_FAILURE);
}
memcpy(pRangeBan->m_sReason, pxbRangeBans.m_pItemDatas[4], pxbRangeBans.m_ui16ItemLengths[4]);
pRangeBan->m_sReason[pxbRangeBans.m_ui16ItemLengths[4]] = '\0';
}
// Do we have who created ban?
if (pxbRangeBans.m_ui16ItemLengths[5] != 0)
{
if (pxbRangeBans.m_ui16ItemLengths[5] > 64)
{
pxbRangeBans.m_ui16ItemLengths[5] = 64;
}
pRangeBan->m_sBy = (char *)malloc(pxbRangeBans.m_ui16ItemLengths[5] + 1);
if (pRangeBan->m_sBy == NULL)
{
AppendDebugLogFormat("[MEM] Cannot allocate %hu bytes for sBy2 in BanManager::Load\n", pxbRangeBans.m_ui16ItemLengths[5] + 1);
exit(EXIT_FAILURE);
}
memcpy(pRangeBan->m_sBy, pxbRangeBans.m_pItemDatas[5], pxbRangeBans.m_ui16ItemLengths[5]);
pRangeBan->m_sBy[pxbRangeBans.m_ui16ItemLengths[5]] = '\0';
}
// it is temporary ban?
if (((pRangeBan->m_ui8Bits & TEMP) == TEMP) == true)
{
if (pxbRangeBans.m_ui16ItemLengths[6] != 8)
{
AppendDebugLogFormat("[ERR] Temp range ban expire time have incorrect lenght %hu in BanManager::Load\n", pxbRangeBans.m_ui16ItemLengths[6]);
exit(EXIT_FAILURE);
}
else
{
// Temporary ban expiration datetime
pRangeBan->m_tTempBanExpire = (time_t)be64toh(*((uint64_t *)(pxbRangeBans.m_pItemDatas[6])));
if (tmAccTime >= pRangeBan->m_tTempBanExpire)
{
delete pRangeBan;
}
else
{
AddRange(pRangeBan);
}
}
}
else
{
AddRange(pRangeBan);
}
bSuccess = pxbRangeBans.ReadNextItem(ui16Identificators, 7);
}
}
//---------------------------------------------------------------------------
void BanManager::LoadXML()
{
double dVer;
#ifdef _WIN32
TiXmlDocument doc((ServerManager::m_sPath + "\\cfg\\BanList.xml").c_str());
#else
TiXmlDocument doc((ServerManager::m_sPath + "/cfg/BanList.xml").c_str());
#endif
if (doc.LoadFile() == false)
{
if (doc.ErrorId() != TiXmlBase::TIXML_ERROR_OPENING_FILE && doc.ErrorId() != TiXmlBase::TIXML_ERROR_DOCUMENT_EMPTY)
{
int iMsgLen = snprintf(ServerManager::m_pGlobalBuffer, ServerManager::m_szGlobalBufferSize, "Error loading file BanList.xml. %s (Col: %d, Row: %d)", doc.ErrorDesc(), doc.Column(), doc.Row());
if (iMsgLen > 0)
{
#ifdef _BUILD_GUI
::MessageBox(NULL, ServerManager::m_pGlobalBuffer, g_sPtokaXTitle, MB_OK | MB_ICONERROR);
#else
AppendLog(ServerManager::m_pGlobalBuffer);
#endif
}
exit(EXIT_FAILURE);
}
}
else
{
TiXmlHandle cfg(&doc);
TiXmlElement *banlist = cfg.FirstChild("BanList").Element();
if (banlist != NULL)
{
if (banlist->Attribute("version", &dVer) == NULL)
{
return;
}
time_t acc_time;
time(&acc_time);
TiXmlNode *bans = banlist->FirstChild("Bans");
if (bans != NULL)
{
TiXmlNode *child = nullptr;
while ((child = bans->IterateChildren(child)) != NULL)
{
const char *ip = NULL, *nick = NULL, *reason = NULL, *by = nullptr;
TiXmlNode *ban = child->FirstChild("Type");
if (ban == NULL || (ban = ban->FirstChild()) == NULL)
{
continue;
}
char type = atoi(ban->Value()) == 0 ? (char)0 : (char)1;
if ((ban = child->FirstChild("IP")) != NULL &&
(ban = ban->FirstChild()) != NULL)
{
ip = ban->Value();
}
if ((ban = child->FirstChild("Nick")) != NULL &&
(ban = ban->FirstChild()) != NULL)
{
nick = ban->Value();
}
if ((ban = child->FirstChild("Reason")) != NULL &&
(ban = ban->FirstChild()) != NULL)
{
reason = ban->Value();
}
if ((ban = child->FirstChild("By")) != NULL &&
(ban = ban->FirstChild()) != NULL)
{
by = ban->Value();
}
if ((ban = child->FirstChild("NickBan")) == NULL ||
(ban = ban->FirstChild()) == NULL)
{
continue;
}
bool nickban = (atoi(ban->Value()) == 0 ? false : true);
if ((ban = child->FirstChild("IpBan")) == NULL ||
(ban = ban->FirstChild()) == NULL)
{
continue;
}
bool ipban = (atoi(ban->Value()) == 0 ? false : true);
if ((ban = child->FirstChild("FullIpBan")) == NULL ||
(ban = ban->FirstChild()) == NULL)
{
continue;
}
bool fullipban = (atoi(ban->Value()) == 0 ? false : true);
BanItem * Ban = new (std::nothrow) BanItem();
if (Ban == NULL)
{
AppendDebugLog("%s - [MEM] Cannot allocate Ban in BanManager::LoadXML\n");
exit(EXIT_FAILURE);
}
if (type == 0)
{
Ban->m_ui8Bits |= PERM;
}
else
{
Ban->m_ui8Bits |= TEMP;
}
// PPK ... ipban
if (ipban == true)
{
if (ip != NULL && HashIP(ip, Ban->m_ui128IpHash) == true)
{
strcpy(Ban->m_sIp, ip);
Ban->m_ui8Bits |= IP;
if (fullipban == true)
{
Ban->m_ui8Bits |= FULL;
}
}
else
{
delete Ban;
continue;
}
}
// PPK ... nickban
if (nickban == true)
{
if (nick != NULL)
{
size_t szNickLen = strlen(nick);
Ban->m_sNick = (char *)malloc(szNickLen + 1);
if (Ban->m_sNick == NULL)
{
AppendDebugLogFormat("[MEM] Cannot allocate %zu bytes for m_sNick in BanManager::LoadXML\n", szNickLen+1);
exit(EXIT_FAILURE);
}
memcpy(Ban->m_sNick, nick, szNickLen);
Ban->m_sNick[szNickLen] = '\0';
Ban->m_ui32NickHash = HashNick(Ban->m_sNick, strlen(Ban->m_sNick));
Ban->m_ui8Bits |= NICK;
}
else
{
delete Ban;
continue;
}
}
if (reason != NULL)
{
size_t szReasonLen = strlen(reason);
if (szReasonLen > 255)
{
szReasonLen = 255;
}
Ban->m_sReason = (char *)malloc(szReasonLen + 1);
if (Ban->m_sReason == NULL)
{
AppendDebugLogFormat("[MEM] Cannot allocate %zu bytes for m_sReason in BanManager::LoadXML\n", szReasonLen+1);
exit(EXIT_FAILURE);
}
memcpy(Ban->m_sReason, reason, szReasonLen);
Ban->m_sReason[szReasonLen] = '\0';
}
if (by != NULL)
{
size_t szByLen = strlen(by);
if (szByLen > 63)
{
szByLen = 63;
}
Ban->m_sBy = (char *)malloc(szByLen + 1);
if (Ban->m_sBy == NULL)
{
AppendDebugLogFormat("[MEM] Cannot allocate %zu bytes for m_sBy1 in BanManager::LoadXML\n", szByLen+1);
exit(EXIT_FAILURE);
}
memcpy(Ban->m_sBy, by, szByLen);
Ban->m_sBy[szByLen] = '\0';
}
// PPK ... temp ban
if (((Ban->m_ui8Bits & TEMP) == TEMP) == true)
{
if ((ban = child->FirstChild("Expire")) == NULL ||
(ban = ban->FirstChild()) == NULL)
{
delete Ban;
continue;
}
time_t expire = strtoul(ban->Value(), NULL, 10);
if (acc_time > expire)
{
delete Ban;
continue;
}
// PPK ... temp ban expiration
Ban->m_tTempBanExpire = expire;
}
if (fullipban == true)
{
Ban->m_ui8Bits |= FULL;
}
if (Add(Ban) == false)
{
exit(EXIT_FAILURE);
}
}
}
TiXmlNode *rangebans = banlist->FirstChild("RangeBans");
if (rangebans != NULL)
{
TiXmlNode *child = nullptr;
while ((child = rangebans->IterateChildren(child)) != NULL)
{
const char *reason = NULL, *by = nullptr;
TiXmlNode *rangeban = child->FirstChild("Type");
if (rangeban == NULL ||
(rangeban = rangeban->FirstChild()) == NULL)
{
continue;
}
char type = atoi(rangeban->Value()) == 0 ? (char)0 : (char)1;
if ((rangeban = child->FirstChild("IpFrom")) == NULL ||
(rangeban = rangeban->FirstChild()) == NULL)
{
continue;
}
const char *ipfrom = rangeban->Value();
if ((rangeban = child->FirstChild("IpTo")) == NULL ||
(rangeban = rangeban->FirstChild()) == NULL)
{
continue;
}
const char *ipto = rangeban->Value();
if ((rangeban = child->FirstChild("Reason")) != NULL &&
(rangeban = rangeban->FirstChild()) != NULL)
{
reason = rangeban->Value();
}
if ((rangeban = child->FirstChild("By")) != NULL &&
(rangeban = rangeban->FirstChild()) != NULL)
{
by = rangeban->Value();
}
if ((rangeban = child->FirstChild("FullIpBan")) == NULL ||
(rangeban = rangeban->FirstChild()) == NULL)
{
continue;
}
bool fullipban = (atoi(rangeban->Value()) == 0 ? false : true);
RangeBanItem * RangeBan = new (std::nothrow) RangeBanItem();
if (RangeBan == NULL)
{
AppendDebugLog("%s - [MEM] Cannot allocate RangeBan in BanManager::LoadXML\n");
exit(EXIT_FAILURE);
}
if (type == 0)
{
RangeBan->m_ui8Bits |= PERM;
}
else
{
RangeBan->m_ui8Bits |= TEMP;
}
// PPK ... fromip
if (HashIP(ipfrom, RangeBan->m_ui128FromIpHash) == true)
{
strcpy(RangeBan->m_sIpFrom, ipfrom);
}
else
{
delete RangeBan;
continue;
}
// PPK ... toip
if (HashIP(ipto, RangeBan->m_ui128ToIpHash) == true && memcmp(RangeBan->m_ui128ToIpHash, RangeBan->m_ui128FromIpHash, 16) > 0)
{
strcpy(RangeBan->m_sIpTo, ipto);
}
else
{
delete RangeBan;
continue;
}
if (reason != NULL)
{
size_t szReasonLen = strlen(reason);
if (szReasonLen > 255)
{
szReasonLen = 255;
}
RangeBan->m_sReason = (char *)malloc(szReasonLen + 1);
if (RangeBan->m_sReason == NULL)
{
AppendDebugLogFormat("[MEM] Cannot allocate %zu bytes for m_sReason3 in BanManager::LoadXML\n", szReasonLen+1);
exit(EXIT_FAILURE);
}
memcpy(RangeBan->m_sReason, reason, szReasonLen);
RangeBan->m_sReason[szReasonLen] = '\0';
}
if (by != NULL)
{
size_t szByLen = strlen(by);
if (szByLen > 63)
{
szByLen = 63;
}
RangeBan->m_sBy = (char *)malloc(szByLen + 1);
if (RangeBan->m_sBy == NULL)
{
AppendDebugLogFormat("[MEM] Cannot allocate %zu bytes for m_sBy3 in BanManager::LoadXML\n", szByLen+1);
exit(EXIT_FAILURE);
}
memcpy(RangeBan->m_sBy, by, szByLen);
RangeBan->m_sBy[szByLen] = '\0';
}
// PPK ... temp ban
if (((RangeBan->m_ui8Bits & TEMP) == TEMP) == true)
{
if ((rangeban = child->FirstChild("Expire")) == NULL ||
(rangeban = rangeban->FirstChild()) == NULL)
{
delete RangeBan;
continue;
}
time_t expire = strtoul(rangeban->Value(), NULL, 10);
if (acc_time > expire)
{
delete RangeBan;
continue;
}
// PPK ... temp ban expiration
RangeBan->m_tTempBanExpire = expire;
}
if (fullipban == true)
{
RangeBan->m_ui8Bits |= FULL;
}
AddRange(RangeBan);
}
}
}
}
}
//---------------------------------------------------------------------------
void BanManager::Save(bool bForce/* = false*/)
{
if (bForce == false)
{
// we don't want waste resources with save after every change in bans
if (m_ui32SaveCalled < 100)
{
m_ui32SaveCalled++;
return;
}
}
m_ui32SaveCalled = 0;
PXBReader pxbBans;
// Open bans file
#ifdef _WIN32
if (pxbBans.OpenFileSave((ServerManager::m_sPath + "\\cfg\\Bans.pxb").c_str(), 9) == false)
{
#else
if (pxbBans.OpenFileSave((ServerManager::m_sPath + "/cfg/Bans.pxb").c_str(), 9) == false)
{
#endif
return;
}
// Write file header
pxbBans.m_sItemIdentifiers[0] = 'F';
pxbBans.m_sItemIdentifiers[1] = 'I';
pxbBans.m_ui16ItemLengths[0] = (uint16_t)szPtokaXBansLen;
pxbBans.m_pItemDatas[0] = (void *)sPtokaXBans;
pxbBans.m_ui8ItemValues[0] = PXBReader::PXB_STRING;
pxbBans.m_sItemIdentifiers[2] = 'F';
pxbBans.m_sItemIdentifiers[3] = 'V';
pxbBans.m_ui16ItemLengths[1] = 4;
uint32_t ui32Version = 1;
pxbBans.m_pItemDatas[1] = (void *)&ui32Version;
pxbBans.m_ui8ItemValues[1] = PXBReader::PXB_FOUR_BYTES;
if (pxbBans.WriteNextItem(szPtokaXBansLen + 4, 2) == false)
{
return;
}
// "BT" "NI" "NB" "IP" "IB" "FB" "RE" "BY" "EX"
memcpy(pxbBans.m_sItemIdentifiers, sBanIds, szBanIdsLen);
pxbBans.m_ui8ItemValues[0] = PXBReader::PXB_BYTE;
pxbBans.m_ui8ItemValues[1] = PXBReader::PXB_STRING;
pxbBans.m_ui8ItemValues[2] = PXBReader::PXB_BYTE;
pxbBans.m_ui8ItemValues[3] = PXBReader::PXB_STRING;
pxbBans.m_ui8ItemValues[4] = PXBReader::PXB_BYTE;
pxbBans.m_ui8ItemValues[5] = PXBReader::PXB_BYTE;
pxbBans.m_ui8ItemValues[6] = PXBReader::PXB_STRING;
pxbBans.m_ui8ItemValues[7] = PXBReader::PXB_STRING;
pxbBans.m_ui8ItemValues[8] = PXBReader::PXB_EIGHT_BYTES;
uint64_t ui64TempBanExpire = 0;
if (m_pTempBanListS != NULL)
{
BanItem * pCur = NULL,
* m_pNext = m_pTempBanListS;
while (m_pNext != NULL)
{
pCur = m_pNext;
m_pNext = pCur->m_pNext;
pxbBans.m_ui16ItemLengths[0] = 1;
pxbBans.m_pItemDatas[0] = (((pCur->m_ui8Bits & PERM) == PERM) == true ? 0 : (void *)1);
pxbBans.m_ui16ItemLengths[1] = pCur->m_sNick == NULL ? 0 : (uint16_t)strlen(pCur->m_sNick);
pxbBans.m_pItemDatas[1] = pCur->m_sNick == NULL ? (void *)"" : (void *)pCur->m_sNick;
pxbBans.m_ui16ItemLengths[2] = 1;
pxbBans.m_pItemDatas[2] = (((pCur->m_ui8Bits & NICK) == NICK) == true ? (void *)1 : 0);
pxbBans.m_ui16ItemLengths[3] = 16;
pxbBans.m_pItemDatas[3] = (void *)pCur->m_ui128IpHash;
pxbBans.m_ui16ItemLengths[4] = 1;
pxbBans.m_pItemDatas[4] = (((pCur->m_ui8Bits & IP) == IP) == true ? (void *)1 : 0);
pxbBans.m_ui16ItemLengths[5] = 1;
pxbBans.m_pItemDatas[5] = (((pCur->m_ui8Bits & FULL) == FULL) == true ? (void *)1 : 0);
pxbBans.m_ui16ItemLengths[6] = pCur->m_sReason == NULL ? 0 : (uint16_t)strlen(pCur->m_sReason);
pxbBans.m_pItemDatas[6] = pCur->m_sReason == NULL ? (void *)"" : (void *)pCur->m_sReason;
pxbBans.m_ui16ItemLengths[7] = pCur->m_sBy == NULL ? 0 : (uint16_t)strlen(pCur->m_sBy);
pxbBans.m_pItemDatas[7] = pCur->m_sBy == NULL ? (void *)"" : (void *)pCur->m_sBy;
pxbBans.m_ui16ItemLengths[8] = 8;
ui64TempBanExpire = (uint64_t)pCur->m_tTempBanExpire;
pxbBans.m_pItemDatas[8] = (void *)&ui64TempBanExpire;
if (pxbBans.WriteNextItem(pxbBans.m_ui16ItemLengths[0] + pxbBans.m_ui16ItemLengths[1] + pxbBans.m_ui16ItemLengths[2] + pxbBans.m_ui16ItemLengths[3] + pxbBans.m_ui16ItemLengths[4] + pxbBans.m_ui16ItemLengths[5] + pxbBans.m_ui16ItemLengths[6] + pxbBans.m_ui16ItemLengths[7] + pxbBans.m_ui16ItemLengths[8], 9) == false)
{
break;
}
}
}
if (m_pPermBanListS != NULL)
{
BanItem * pCur = NULL,
* m_pNext = m_pPermBanListS;
while (m_pNext != NULL)
{
pCur = m_pNext;
m_pNext = pCur->m_pNext;
pxbBans.m_ui16ItemLengths[0] = 1;
pxbBans.m_pItemDatas[0] = (((pCur->m_ui8Bits & PERM) == PERM) == true ? 0 : (void *)1);
pxbBans.m_ui16ItemLengths[1] = pCur->m_sNick == NULL ? 0 : (uint16_t)strlen(pCur->m_sNick);
pxbBans.m_pItemDatas[1] = pCur->m_sNick == NULL ? (void *)"" : (void *)pCur->m_sNick;
pxbBans.m_ui16ItemLengths[2] = 1;
pxbBans.m_pItemDatas[2] = (((pCur->m_ui8Bits & NICK) == NICK) == true ? (void *)1 : 0);
pxbBans.m_ui16ItemLengths[3] = 16;
pxbBans.m_pItemDatas[3] = (void *)pCur->m_ui128IpHash;
pxbBans.m_ui16ItemLengths[4] = 1;
pxbBans.m_pItemDatas[4] = (((pCur->m_ui8Bits & IP) == IP) == true ? (void *)1 : 0);
pxbBans.m_ui16ItemLengths[5] = 1;
pxbBans.m_pItemDatas[5] = (((pCur->m_ui8Bits & FULL) == FULL) == true ? (void *)1 : 0);
pxbBans.m_ui16ItemLengths[6] = pCur->m_sReason == NULL ? 0 : (uint16_t)strlen(pCur->m_sReason);
pxbBans.m_pItemDatas[6] = pCur->m_sReason == NULL ? (void *)"" : (void *)pCur->m_sReason;
pxbBans.m_ui16ItemLengths[7] = pCur->m_sBy == NULL ? 0 : (uint16_t)strlen(pCur->m_sBy);
pxbBans.m_pItemDatas[7] = pCur->m_sBy == NULL ? (void *)"" : (void *)pCur->m_sBy;
pxbBans.m_ui16ItemLengths[8] = 8;
ui64TempBanExpire = (uint64_t)pCur->m_tTempBanExpire;
pxbBans.m_pItemDatas[8] = (void *)&ui64TempBanExpire;
if (pxbBans.WriteNextItem(pxbBans.m_ui16ItemLengths[0] + pxbBans.m_ui16ItemLengths[1] + pxbBans.m_ui16ItemLengths[2] + pxbBans.m_ui16ItemLengths[3] + pxbBans.m_ui16ItemLengths[4] + pxbBans.m_ui16ItemLengths[5] + pxbBans.m_ui16ItemLengths[6] + pxbBans.m_ui16ItemLengths[7] + pxbBans.m_ui16ItemLengths[8], 9) == false)
{
break;
}
}
}
pxbBans.WriteRemaining();
PXBReader pxbRangeBans;
// Open range bans file
#ifdef _WIN32
if (pxbRangeBans.OpenFileSave((ServerManager::m_sPath + "\\cfg\\RangeBans.pxb").c_str(), 7) == false)
{
#else
if (pxbRangeBans.OpenFileSave((ServerManager::m_sPath + "/cfg/RangeBans.pxb").c_str(), 7) == false)
{
#endif
return;
}
// Write file header
pxbRangeBans.m_sItemIdentifiers[0] = 'F';
pxbRangeBans.m_sItemIdentifiers[1] = 'I';
pxbRangeBans.m_ui16ItemLengths[0] = (uint16_t)szPtokaXRangeBansLen;
pxbRangeBans.m_pItemDatas[0] = (void *)sPtokaXRangeBans;
pxbRangeBans.m_ui8ItemValues[0] = PXBReader::PXB_STRING;
pxbRangeBans.m_sItemIdentifiers[2] = 'F';
pxbRangeBans.m_sItemIdentifiers[3] = 'V';
pxbRangeBans.m_ui16ItemLengths[1] = 4;
pxbRangeBans.m_pItemDatas[1] = (void *)&ui32Version;
pxbRangeBans.m_ui8ItemValues[1] = PXBReader::PXB_FOUR_BYTES;
if (pxbRangeBans.WriteNextItem(szPtokaXRangeBansLen + 4, 2) == false)
{
return;
}
// "BT" "RF" "RT" "FB" "RE" "BY" "EX"
memcpy(pxbRangeBans.m_sItemIdentifiers, sRangeBanIds, szRangeBanIdsLen);
pxbRangeBans.m_ui8ItemValues[0] = PXBReader::PXB_BYTE;
pxbRangeBans.m_ui8ItemValues[1] = PXBReader::PXB_STRING;
pxbRangeBans.m_ui8ItemValues[2] = PXBReader::PXB_STRING;
pxbRangeBans.m_ui8ItemValues[3] = PXBReader::PXB_BYTE;
pxbRangeBans.m_ui8ItemValues[4] = PXBReader::PXB_STRING;
pxbRangeBans.m_ui8ItemValues[5] = PXBReader::PXB_STRING;
pxbRangeBans.m_ui8ItemValues[6] = PXBReader::PXB_EIGHT_BYTES;
if (m_pRangeBanListS != NULL)
{
RangeBanItem * pCur = NULL,
* m_pNext = m_pRangeBanListS;
while (m_pNext != NULL)
{
pCur = m_pNext;
m_pNext = pCur->m_pNext;
pxbRangeBans.m_ui16ItemLengths[0] = 1;
pxbRangeBans.m_pItemDatas[0] = (((pCur->m_ui8Bits & PERM) == PERM) == true ? 0 : (void *)1);
pxbRangeBans.m_ui16ItemLengths[1] = 16;
pxbRangeBans.m_pItemDatas[1] = (void *)pCur->m_ui128FromIpHash;
pxbRangeBans.m_ui16ItemLengths[2] = 16;
pxbRangeBans.m_pItemDatas[2] = (void *)pCur->m_ui128ToIpHash;
pxbRangeBans.m_ui16ItemLengths[3] = 1;
pxbRangeBans.m_pItemDatas[3] = (((pCur->m_ui8Bits & FULL) == FULL) == true ? (void *)1 : 0);
pxbRangeBans.m_ui16ItemLengths[4] = pCur->m_sReason == NULL ? 0 : (uint16_t)strlen(pCur->m_sReason);
pxbRangeBans.m_pItemDatas[4] = pCur->m_sReason == NULL ? (void *)"" : (void *)pCur->m_sReason;
pxbRangeBans.m_ui16ItemLengths[5] = pCur->m_sBy == NULL ? 0 : (uint16_t)strlen(pCur->m_sBy);
pxbRangeBans.m_pItemDatas[5] = pCur->m_sBy == NULL ? (void *)"" : (void *)pCur->m_sBy;
pxbRangeBans.m_ui16ItemLengths[6] = 8;
ui64TempBanExpire = (uint64_t)pCur->m_tTempBanExpire;
pxbRangeBans.m_pItemDatas[6] = (void *)&ui64TempBanExpire;
if (pxbRangeBans.WriteNextItem(pxbRangeBans.m_ui16ItemLengths[0] + pxbRangeBans.m_ui16ItemLengths[1] + pxbRangeBans.m_ui16ItemLengths[2] + pxbRangeBans.m_ui16ItemLengths[3] + pxbRangeBans.m_ui16ItemLengths[4] + pxbRangeBans.m_ui16ItemLengths[5] + pxbRangeBans.m_ui16ItemLengths[6], 7) == false)
{
break;
}
}
}
pxbRangeBans.WriteRemaining();
}
//---------------------------------------------------------------------------
void BanManager::ClearTemp(void)
{
BanItem * curBan = NULL,
* nextBan = m_pTempBanListS;
while (nextBan != NULL)
{
curBan = nextBan;
nextBan = curBan->m_pNext;
Rem(curBan);
delete curBan;
}
Save();
}
//---------------------------------------------------------------------------
void BanManager::ClearPerm(void)
{
BanItem * curBan = NULL,
* nextBan = m_pPermBanListS;
while (nextBan != NULL)
{
curBan = nextBan;
nextBan = curBan->m_pNext;
Rem(curBan);
delete curBan;
}
Save();
}
//---------------------------------------------------------------------------
void BanManager::ClearRange(void)
{
RangeBanItem * curBan = NULL,
* nextBan = m_pRangeBanListS;
while (nextBan != NULL)
{
curBan = nextBan;
nextBan = curBan->m_pNext;
RemRange(curBan);
delete curBan;
}
Save();
}
//---------------------------------------------------------------------------
void BanManager::ClearTempRange(void)
{
RangeBanItem * curBan = NULL,
* nextBan = m_pRangeBanListS;
while (nextBan != NULL)
{
curBan = nextBan;
nextBan = curBan->m_pNext;
if (((curBan->m_ui8Bits & TEMP) == TEMP) == true)
{
RemRange(curBan);
delete curBan;
}
}
Save();
}
//---------------------------------------------------------------------------
void BanManager::ClearPermRange(void)
{
RangeBanItem * curBan = NULL,
* nextBan = m_pRangeBanListS;
while (nextBan != NULL)
{
curBan = nextBan;
nextBan = curBan->m_pNext;
if (((curBan->m_ui8Bits & PERM) == PERM) == true)
{
RemRange(curBan);
delete curBan;
}
}
Save();
}
//---------------------------------------------------------------------------
void BanManager::Ban(User * pUser, const char * sReason, const char * sBy, const bool bFull)
{
BanItem * pBan = new (std::nothrow) BanItem();
if (pBan == NULL)
{
AppendDebugLog("%s - [MEM] Cannot allocate pBan in BanManager::Ban\n");
return;
}
pBan->m_ui8Bits |= PERM;
pBan->initIP( pUser);
pBan->m_ui8Bits |= IP;
if (bFull == true)
{
pBan->m_ui8Bits |= FULL;
}
time_t acc_time;
time(&acc_time);
// PPK ... check for <unknown> nick -> bad ban from script
if (pUser->m_sNick[0] != '<')
{
pBan->m_sNick = (char *)malloc(pUser->m_ui8NickLen + 1);
if (pBan->m_sNick == NULL)
{
delete pBan;
AppendDebugLogFormat("[MEM] Cannot allocate %" PRIu8 " bytes for sNick in BanManager::Ban\n", pUser->m_ui8NickLen + 1);
return;
}
memcpy(pBan->m_sNick, pUser->m_sNick, pUser->m_ui8NickLen);
pBan->m_sNick[pUser->m_ui8NickLen] = '\0';
pBan->m_ui32NickHash = pUser->m_ui32NickHash;
pBan->m_ui8Bits |= NICK;
// PPK ... not allow same nickbans ! i don't want this check here, but lame scripter find way to ban same nick/ip multiple times :(
BanItem * nxtBan = FindNick(pBan->m_ui32NickHash, acc_time, pBan->m_sNick);
if (nxtBan != NULL)
{
if (((nxtBan->m_ui8Bits & PERM) == PERM) == true)
{
if (((nxtBan->m_ui8Bits & IP) == IP) == true)
{
if (memcmp(pBan->m_ui128IpHash, nxtBan->m_ui128IpHash, 16) == 0)
{
if (((pBan->m_ui8Bits & FULL) == FULL) == false)
{
// PPK ... same ban and new is not full, delete new
delete pBan;
return;
}
else
{
if (((nxtBan->m_ui8Bits & FULL) == FULL) == true)
{
// PPK ... same ban and both full, delete new
delete pBan;
return;
}
else
{
// PPK ... same ban but only new is full, delete old
Rem(nxtBan);
delete nxtBan;
}
}
}
else
{
pBan->m_ui8Bits &= ~NICK;
}
}
else
{
// PPK ... old ban is only nickban, remove it
Rem(nxtBan);
delete nxtBan;
}
}
else
{
if (((nxtBan->m_ui8Bits & IP) == IP) == true)
{
if (memcmp(pBan->m_ui128IpHash, nxtBan->m_ui128IpHash, 16) == 0)
{
if (((nxtBan->m_ui8Bits & FULL) == FULL) == false)
{
// PPK ... same ban and old is only temp, delete old
Rem(nxtBan);
delete nxtBan;
}
else
{
if (((pBan->m_ui8Bits & FULL) == FULL) == true)
{
// PPK ... same full ban and old is only temp, delete old
Rem(nxtBan);
delete nxtBan;
}
else
{
// PPK ... old ban is full, new not... set old ban to only ipban
RemFromNickTable(nxtBan);
nxtBan->m_ui8Bits &= ~NICK;
}
}
}
else
{
// PPK ... set old ban to ip ban only
RemFromNickTable(nxtBan);
nxtBan->m_ui8Bits &= ~NICK;
}
}
else
{
// PPK ... old ban is only nickban, remove it
Rem(nxtBan);
delete nxtBan;
}
}
}
}
// PPK ... clear bans with same ip without nickban and fullban if new ban is fullban
BanItem * curBan = NULL,
* nxtBan = FindIP(pBan->m_ui128IpHash, acc_time);
while (nxtBan != NULL)
{
curBan = nxtBan;
nxtBan = curBan->m_pHashIpTableNext;
if (((curBan->m_ui8Bits & NICK) == NICK) == true)
{
continue;
}
if (((curBan->m_ui8Bits & FULL) == FULL) == true && ((pBan->m_ui8Bits & FULL) == FULL) == false)
{
continue;
}
Rem(curBan);
delete curBan;
}
if (sReason != NULL)
{
size_t szReasonLen = strlen(sReason);
pBan->m_sReason = (char *)malloc(szReasonLen > 511 ? 512 : szReasonLen + 1);
if (pBan->m_sReason == NULL)
{
delete pBan;
AppendDebugLogFormat("[MEM] Cannot allocate %zu bytes for sReason in BanManager::Ban\n", szReasonLen > 511 ? 512 : szReasonLen+1);
return;
}
if (szReasonLen > 511)
{
memcpy(pBan->m_sReason, sReason, 508);
pBan->m_sReason[510] = '.';
pBan->m_sReason[509] = '.';
pBan->m_sReason[508] = '.';
szReasonLen = 511;
}
else
{
memcpy(pBan->m_sReason, sReason, szReasonLen);
}
pBan->m_sReason[szReasonLen] = '\0';
}
if (AddBanInternal(sBy, pBan) == false)
{
return;
}
if (Add(pBan) == false)
{
delete pBan;
return;
}
Save();
}
//---------------------------------------------------------------------------
bool BanManager::AddBanInternal(const char * sBy, BanItemBase * pBan)
{
if (sBy != NULL)
{
size_t szByLen = strlen(sBy);
if (szByLen > 63)
{
szByLen = 63;
}
pBan->m_sBy = (char *)malloc(szByLen + 1);
if (pBan->m_sBy == NULL)
{
delete pBan;
AppendDebugLogFormat("[MEM] Cannot allocate %zu bytes for m_sBy in BanManager::Ban\n", szByLen+1);
return false;
}
memcpy(pBan->m_sBy, sBy, szByLen);
pBan->m_sBy[szByLen] = '\0';
}
return true;
}
//---------------------------------------------------------------------------
static bool CreateReason(BanItemBase * pBan, const char * sReason)
{
if (sReason != NULL)
{
size_t szReasonLen = strlen(sReason);
pBan->m_sReason = (char *)malloc(szReasonLen > 511 ? 512 : szReasonLen + 1);
if (pBan->m_sReason == NULL)
{
delete pBan;
AppendDebugLogFormat("[MEM] Cannot allocate %zu bytes CreateReason\n", szReasonLen > 511 ? 512 : szReasonLen + 1);
return true;
}
if (szReasonLen > 511)
{
memcpy(pBan->m_sReason, sReason, 508);
pBan->m_sReason[510] = '.';
pBan->m_sReason[509] = '.';
pBan->m_sReason[508] = '.';
szReasonLen = 511;
}
else
{
memcpy(pBan->m_sReason, sReason, szReasonLen);
}
pBan->m_sReason[szReasonLen] = '\0';
}
return false;
}
char BanManager::BanIp(User * pUser, const char * sIp, const char * sReason, const char * sBy, const bool bFull)
{
BanItem * pBan = new (std::nothrow) BanItem();
if (pBan == NULL)
{
AppendDebugLog("%s - [MEM] Cannot allocate pBan in BanManager::BanIp\n");
return 1;
}
pBan->m_ui8Bits |= PERM;
if (pUser)
{
pBan->initIP( pUser);
}
else
{
if (sIp != NULL && HashIP(sIp, pBan->m_ui128IpHash) == true)
{
pBan->initIP(sIp);
}
else
{
delete pBan;
return 1;
}
}
pBan->m_ui8Bits |= IP;
if (bFull == true)
{
pBan->m_ui8Bits |= FULL;
}
time_t acc_time;
time(&acc_time);
BanItem * curBan = NULL,
* nxtBan = FindIP(pBan->m_ui128IpHash, acc_time);
// PPK ... don't add ban if is already here perm (full) ban for same ip
while (nxtBan != NULL)
{
curBan = nxtBan;
nxtBan = curBan->m_pHashIpTableNext;
if (((curBan->m_ui8Bits & TEMP) == TEMP) == true)
{
if (((curBan->m_ui8Bits & FULL) == FULL) == false || ((pBan->m_ui8Bits & FULL) == FULL) == true)
{
if (((curBan->m_ui8Bits & NICK) == NICK) == false)
{
Rem(curBan);
delete curBan;
}
continue;
}
continue;
}
if (((curBan->m_ui8Bits & FULL) == FULL) == false && ((pBan->m_ui8Bits & FULL) == FULL) == true)
{
if (((curBan->m_ui8Bits & NICK) == NICK) == false)
{
Rem(curBan);
delete curBan;
}
continue;
}
delete pBan;
return 2;
}
if (CreateReason(pBan, sReason))
return 1;
if (AddBanInternal(sBy, pBan) == false)
{
return 1;
}
if (Add(pBan) == false)
{
delete pBan;
return 1;
}
Save();
return 0;
}
//---------------------------------------------------------------------------
bool BanManager::NickBan(User * pUser, const char * sNick, const char * sReason, const char * sBy)
{
BanItem * pBan = new (std::nothrow) BanItem();
if (pBan == NULL)
{
AppendDebugLog("%s - [MEM] Cannot allocate pBan in BanManager::NickBan\n");
return false;
}
pBan->m_ui8Bits |= PERM;
if (!pUser)
{
// PPK ... this should never happen, but to be sure ;)
if (sNick == NULL)
{
delete pBan;
return false;
}
// PPK ... bad script ban check
if (sNick[0] == '<')
{
delete pBan;
return false;
}
size_t szNickLen = strlen(sNick);
pBan->m_sNick = (char *)malloc(szNickLen + 1);
if (pBan->m_sNick == NULL)
{
delete pBan;
AppendDebugLogFormat("[MEM] Cannot allocate %zu bytes for m_sNick in BanManager::NickBan\n", szNickLen+1);
return false;
}
memcpy(pBan->m_sNick, sNick, szNickLen);
pBan->m_sNick[szNickLen] = '\0';
pBan->m_ui32NickHash = HashNick(sNick, szNickLen);
}
else
{
// PPK ... bad script ban check
if (pUser->m_sNick[0] == '<')
{
delete pBan;
return false;
}
pBan->m_sNick = (char *)malloc(pUser->m_ui8NickLen + 1);
if (pBan->m_sNick == NULL)
{
delete pBan;
AppendDebugLogFormat("[MEM] Cannot allocate %" PRIu8 " bytes for sNick1 in BanManager::NickBan\n", pUser->m_ui8NickLen + 1);
return false;
}
memcpy(pBan->m_sNick, pUser->m_sNick, pUser->m_ui8NickLen);
pBan->m_sNick[pUser->m_ui8NickLen] = '\0';
pBan->m_ui32NickHash = pUser->m_ui32NickHash;
pBan->initIP( pUser);
}
pBan->m_ui8Bits |= NICK;
time_t acc_time;
time(&acc_time);
BanItem *nxtBan = FindNick(pBan->m_ui32NickHash, acc_time, pBan->m_sNick);
// PPK ... not allow same nickbans !
if (nxtBan != NULL)
{
if (((nxtBan->m_ui8Bits & PERM) == PERM) == true)
{
delete pBan;
return false;
}
else
{
if (((nxtBan->m_ui8Bits & IP) == IP) == true)
{
// PPK ... set old ban to ip ban only
RemFromNickTable(nxtBan);
nxtBan->m_ui8Bits &= ~NICK;
}
else
{
// PPK ... old ban is only nickban, remove it
Rem(nxtBan);
delete nxtBan;
}
}
}
if (CreateReason(pBan, sReason))
{
return false;
}
if (AddBanInternal(sBy, pBan) == false)
{
return false;
}
if (Add(pBan) == false)
{
delete pBan;
return false;
}
Save();
return true;
}
//---------------------------------------------------------------------------
void BanManager::TempBan(User * pUser, const char * sReason, const char * sBy, const uint32_t minutes, const time_t &expiretime, const bool bFull)
{
BanItem * pBan = new (std::nothrow) BanItem();
if (pBan == NULL)
{
AppendDebugLog("%s - [MEM] Cannot allocate pBan in BanManager::TempBan\n");
return;
}
pBan->m_ui8Bits |= TEMP;
pBan->initIP( pUser);
pBan->m_ui8Bits |= IP;
if (bFull == true)
{
pBan->m_ui8Bits |= FULL;
}
time_t acc_time;
time(&acc_time);
if (expiretime > 0)
{
pBan->m_tTempBanExpire = expiretime;
}
else
{
if (minutes > 0)
{
pBan->m_tTempBanExpire = acc_time + (minutes * 60);
}
else
{
pBan->m_tTempBanExpire = acc_time + (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_DEFAULT_TEMP_BAN_TIME] * 60);
}
}
// PPK ... check for <unknown> nick -> bad ban from script
if (pUser->m_sNick[0] != '<')
{
size_t szNickLen = strlen(pUser->m_sNick);
pBan->m_sNick = (char *)malloc(szNickLen + 1);
if (pBan->m_sNick == NULL)
{
delete pBan;
AppendDebugLogFormat("[MEM] Cannot allocate %zu bytes for m_sNick in BanManager::TempBan\n", szNickLen+1);
return;
}
memcpy(pBan->m_sNick, pUser->m_sNick, szNickLen);
pBan->m_sNick[szNickLen] = '\0';
pBan->m_ui32NickHash = pUser->m_ui32NickHash;
pBan->m_ui8Bits |= NICK;
// PPK ... not allow same nickbans ! i don't want this check here, but lame scripter find way to ban same nick multiple times :(
BanItem *nxtBan = FindNick(pBan->m_ui32NickHash, acc_time, pBan->m_sNick);
if (nxtBan != NULL)
{
if (((nxtBan->m_ui8Bits & PERM) == PERM) == true)
{
if (((nxtBan->m_ui8Bits & IP) == IP) == true)
{
if (memcmp(pBan->m_ui128IpHash, nxtBan->m_ui128IpHash, 16) == 0)
{
if (((pBan->m_ui8Bits & FULL) == FULL) == false)
{
// PPK ... same ban and old is perm, delete new
delete pBan;
return;
}
else
{
if (((nxtBan->m_ui8Bits & FULL) == FULL) == true)
{
// PPK ... same ban and old is full perm, delete new
delete pBan;
return;
}
else
{
// PPK ... same ban and only new is full, set new to ipban only
pBan->m_ui8Bits &= ~NICK;
}
}
}
}
else
{
// PPK ... perm ban to same nick already exist, set new to ipban only
pBan->m_ui8Bits &= ~NICK;
}
}
else
{
if (nxtBan->m_tTempBanExpire < pBan->m_tTempBanExpire)
{
if (((nxtBan->m_ui8Bits & IP) == IP) == true)
{
if (memcmp(pBan->m_ui128IpHash, nxtBan->m_ui128IpHash, 16) == 0)
{
if (((nxtBan->m_ui8Bits & FULL) == FULL) == false)
{
// PPK ... same bans, but old with lower expiration -> delete old
Rem(nxtBan);
delete nxtBan;
}
else
{
if (((pBan->m_ui8Bits & FULL) == FULL) == false)
{
// PPK ... old ban with lower expiration is full ban, set old to ipban only
RemFromNickTable(nxtBan);
nxtBan->m_ui8Bits &= ~NICK;
}
else
{
// PPK ... same bans, old have lower expiration -> delete old
Rem(nxtBan);
delete nxtBan;
}
}
}
else
{
// PPK ... set old ban to ipban only
RemFromNickTable(nxtBan);
nxtBan->m_ui8Bits &= ~NICK;
}
}
else
{
// PPK ... old ban is only nickban with lower bantime, remove it
Rem(nxtBan);
delete nxtBan;
}
}
else
{
if (((nxtBan->m_ui8Bits & IP) == IP) == true)
{
if (memcmp(pBan->m_ui128IpHash, nxtBan->m_ui128IpHash, 16) == 0)
{
if (((pBan->m_ui8Bits & FULL) == FULL) == false)
{
// PPK ... same bans, but new with lower expiration -> delete new
delete pBan;
return;
}
else
{
if (((nxtBan->m_ui8Bits & FULL) == FULL) == false)
{
// PPK ... new ban with lower expiration is full ban, set new to ipban only
pBan->m_ui8Bits &= ~NICK;
}
else
{
// PPK ... same bans, new have lower expiration -> delete new
delete pBan;
return;
}
}
}
else
{
// PPK ... set new ban to ipban only
pBan->m_ui8Bits &= ~NICK;
}
}
else
{
// PPK ... old ban is only nickban with higher bantime, set new to ipban only
pBan->m_ui8Bits &= ~NICK;
}
}
}
}
}
// PPK ... clear bans with lower timeban and same ip without nickban and fullban if new ban is fullban
BanItem * curBan = NULL,
* nxtBan = FindIP(pBan->m_ui128IpHash, acc_time);
while (nxtBan != NULL)
{
curBan = nxtBan;
nxtBan = curBan->m_pHashIpTableNext;
if (((curBan->m_ui8Bits & PERM) == PERM) == true)
{
continue;
}
if (((curBan->m_ui8Bits & NICK) == NICK) == true)
{
continue;
}
if (((curBan->m_ui8Bits & FULL) == FULL) == true && ((pBan->m_ui8Bits & FULL) == FULL) == false)
{
continue;
}
if (curBan->m_tTempBanExpire > pBan->m_tTempBanExpire)
{
continue;
}
Rem(curBan);
delete curBan;
}
if (CreateReason(pBan, sReason))
{
return;
}
if (AddBanInternal(sBy, pBan) == false)
{
return;
}
if (Add(pBan) == false)
{
delete pBan;
return;
}
Save();
}
//---------------------------------------------------------------------------
char BanManager::TempBanIp(User * pUser, const char * sIp, const char * sReason, const char * sBy, const uint32_t minutes, const time_t &expiretime, const bool bFull)
{
BanItem * pBan = new (std::nothrow) BanItem();
if (pBan == NULL)
{
AppendDebugLog("%s - [MEM] Cannot allocate pBan in BanManager::TempBanIp\n");
return 1;
}
pBan->m_ui8Bits |= TEMP;
if (pUser != NULL)
{
pBan->initIP( pUser);
}
else
{
if (sIp != NULL && HashIP(sIp, pBan->m_ui128IpHash) == true)
{
pBan->initIP(sIp);
}
else
{
delete pBan;
return 1;
}
}
pBan->m_ui8Bits |= IP;
if (bFull == true)
{
pBan->m_ui8Bits |= FULL;
}
time_t acc_time;
time(&acc_time);
if (expiretime > 0)
{
pBan->m_tTempBanExpire = expiretime;
}
else
{
if (minutes == 0)
{
pBan->m_tTempBanExpire = acc_time + (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_DEFAULT_TEMP_BAN_TIME] * 60);
}
else
{
pBan->m_tTempBanExpire = acc_time + (minutes * 60);
}
}
BanItem * curBan = NULL,
* nxtBan = FindIP(pBan->m_ui128IpHash, acc_time);
// PPK ... don't add ban if is already here perm (full) ban or longer temp ban for same ip
while (nxtBan != NULL)
{
curBan = nxtBan;
nxtBan = curBan->m_pHashIpTableNext;
if (((curBan->m_ui8Bits & TEMP) == TEMP) == true && curBan->m_tTempBanExpire < pBan->m_tTempBanExpire)
{
if (((curBan->m_ui8Bits & FULL) == FULL) == false || ((pBan->m_ui8Bits & FULL) == FULL) == true)
{
if (((curBan->m_ui8Bits & NICK) == NICK) == false)
{
Rem(curBan);
delete curBan;
}
continue;
}
continue;
}
if (((curBan->m_ui8Bits & FULL) == FULL) == false && ((pBan->m_ui8Bits & FULL) == FULL) == true) continue;
delete pBan;
return 2;
}
if (CreateReason(pBan, sReason))
{
return 1;
}
if (AddBanInternal(sBy, pBan) == false)
{
return 1;
}
if (Add(pBan) == false)
{
delete pBan;
return 1;
}
Save();
return 0;
}
//---------------------------------------------------------------------------
bool BanManager::NickTempBan(User * pUser, const char * sNick, const char * sReason, const char * sBy, const uint32_t minutes, const time_t &expiretime)
{
BanItem * pBan = new (std::nothrow) BanItem();
if (pBan == NULL)
{
AppendDebugLog("%s - [MEM] Cannot allocate pBan in BanManager::NickTempBan\n");
return false;
}
pBan->m_ui8Bits |= TEMP;
if (!pUser)
{
// PPK ... this should never happen, but to be sure ;)
if (sNick == NULL)
{
delete pBan;
return false;
}
// PPK ... bad script ban check
if (sNick[0] == '<')
{
delete pBan;
return false;
}
size_t szNickLen = strlen(sNick);
pBan->m_sNick = (char *)malloc(szNickLen + 1);
if (pBan->m_sNick == NULL)
{
delete pBan;
AppendDebugLogFormat("[MEM] Cannot allocate %zu bytes for m_sNick in BanManager::NickTempBan\n", szNickLen+1);
return false;
}
memcpy(pBan->m_sNick, sNick, szNickLen);
pBan->m_sNick[szNickLen] = '\0';
pBan->m_ui32NickHash = HashNick(sNick, szNickLen);
}
else
{
// PPK ... bad script ban check
if (pUser->m_sNick[0] == '<')
{
delete pBan;
return false;
}
pBan->m_sNick = (char *)malloc(pUser->m_ui8NickLen + 1);
if (pBan->m_sNick == NULL)
{
delete pBan;
AppendDebugLogFormat("[MEM] Cannot allocate %" PRIu8 " bytes for sNick1 in BanManager::NickTempBan\n", pUser->m_ui8NickLen + 1);
return false;
}
memcpy(pBan->m_sNick, pUser->m_sNick, pUser->m_ui8NickLen);
pBan->m_sNick[pUser->m_ui8NickLen] = '\0';
pBan->m_ui32NickHash = pUser->m_ui32NickHash;
pBan->initIP( pUser);
}
pBan->m_ui8Bits |= NICK;
time_t acc_time;
time(&acc_time);
if (expiretime > 0)
{
pBan->m_tTempBanExpire = expiretime;
}
else
{
if (minutes > 0)
{
pBan->m_tTempBanExpire = acc_time + (minutes * 60);
}
else
{
pBan->m_tTempBanExpire = acc_time + (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_DEFAULT_TEMP_BAN_TIME] * 60);
}
}
BanItem *nxtBan = FindNick(pBan->m_ui32NickHash, acc_time, pBan->m_sNick);
// PPK ... not allow same nickbans !
if (nxtBan != NULL)
{
if (((nxtBan->m_ui8Bits & PERM) == PERM) == true)
{
delete pBan;
return false;
}
else
{
if (nxtBan->m_tTempBanExpire < pBan->m_tTempBanExpire)
{
if (((nxtBan->m_ui8Bits & IP) == IP) == true)
{
// PPK ... set old ban to ip ban only
RemFromNickTable(nxtBan);
nxtBan->m_ui8Bits &= ~NICK;
}
else
{
// PPK ... old ban is only nickban, remove it
Rem(nxtBan);
delete nxtBan;
}
}
else
{
delete pBan;
return false;
}
}
}
if (CreateReason(pBan, sReason))
{
return false;
}
if (AddBanInternal(sBy, pBan) == false)
{
return false;
}
if (Add(pBan) == false)
{
delete pBan;
return false;
}
Save();
return true;
}
//---------------------------------------------------------------------------
bool BanManager::Unban(const char * sWhat)
{
uint32_t hash = HashNick(sWhat, strlen(sWhat));
time_t acc_time;
time(&acc_time);
BanItem *Ban = FindNick(hash, acc_time, sWhat);
if (Ban == NULL)
{
Hash128 ui128Hash;
if (HashIP(sWhat, ui128Hash) == true && (Ban = FindIP(ui128Hash, acc_time)) != NULL)
{
Rem(Ban);
delete Ban;
}
else
{
return false;
}
}
else
{
Rem(Ban);
delete Ban;
}
Save();
return true;
}
//---------------------------------------------------------------------------
bool BanManager::PermUnban(const char * sWhat)
{
uint32_t hash = HashNick(sWhat, strlen(sWhat));
BanItem *Ban = FindPermNick(hash, sWhat);
if (Ban == NULL)
{
Hash128 ui128Hash;
if (HashIP(sWhat, ui128Hash) == true && (Ban = FindPermIP(ui128Hash)) != NULL)
{
Rem(Ban);
delete Ban;
}
else
{
return false;
}
}
else
{
Rem(Ban);
delete Ban;
}
Save();
return true;
}
//---------------------------------------------------------------------------
bool BanManager::TempUnban(const char * sWhat)
{
uint32_t hash = HashNick(sWhat, strlen(sWhat));
time_t acc_time;
time(&acc_time);
BanItem *Ban = FindTempNick(hash, acc_time, sWhat);
if (Ban == NULL)
{
Hash128 ui128Hash;
if (HashIP(sWhat, ui128Hash) == true && (Ban = FindTempIP(ui128Hash, acc_time)) != NULL)
{
Rem(Ban);
delete Ban;
}
else
{
return false;
}
}
else
{
Rem(Ban);
delete Ban;
}
Save();
return true;
}
//---------------------------------------------------------------------------
void BanManager::RemoveAllIP(const uint8_t * m_ui128IpHash)
{
uint16_t ui16IpTableIdx = 0;
if (IN6_IS_ADDR_V4MAPPED((const in6_addr *)m_ui128IpHash))
{
ui16IpTableIdx = m_ui128IpHash[14] * m_ui128IpHash[15];
}
else
{
ui16IpTableIdx = GetIpTableIdx(m_ui128IpHash);
}
IpTableItem * cur = NULL,
* next = m_pIpBanTable[ui16IpTableIdx];
BanItem * curBan = NULL, * nextBan = nullptr;
while (next != NULL)
{
cur = next;
next = cur->m_pNext;
if (memcmp(cur->pFirstBan->m_ui128IpHash, m_ui128IpHash, 16) == 0)
{
nextBan = cur->pFirstBan;
while (nextBan != NULL)
{
curBan = nextBan;
nextBan = curBan->m_pHashIpTableNext;
Rem(curBan);
delete curBan;
}
return;
}
}
}
//---------------------------------------------------------------------------
void BanManager::RemovePermAllIP(const uint8_t * m_ui128IpHash)
{
uint16_t ui16IpTableIdx = 0;
if (IN6_IS_ADDR_V4MAPPED((const in6_addr *)m_ui128IpHash))
{
ui16IpTableIdx = m_ui128IpHash[14] * m_ui128IpHash[15];
}
else
{
ui16IpTableIdx = GetIpTableIdx(m_ui128IpHash);
}
IpTableItem * cur = NULL,
* next = m_pIpBanTable[ui16IpTableIdx];
BanItem * curBan = NULL, * nextBan = nullptr;
while (next != NULL)
{
cur = next;
next = cur->m_pNext;
if (memcmp(cur->pFirstBan->m_ui128IpHash, m_ui128IpHash, 16) == 0)
{
nextBan = cur->pFirstBan;
while (nextBan != NULL)
{
curBan = nextBan;
nextBan = curBan->m_pHashIpTableNext;
if (((curBan->m_ui8Bits & BanManager::PERM) == BanManager::PERM) == true)
{
Rem(curBan);
delete curBan;
}
}
return;
}
}
}
//---------------------------------------------------------------------------
void BanManager::RemoveTempAllIP(const uint8_t * m_ui128IpHash)
{
uint16_t ui16IpTableIdx = 0;
if (IN6_IS_ADDR_V4MAPPED((const in6_addr *)m_ui128IpHash))
{
ui16IpTableIdx = m_ui128IpHash[14] * m_ui128IpHash[15];
}
else
{
ui16IpTableIdx = GetIpTableIdx(m_ui128IpHash);
}
IpTableItem * cur = NULL,
* next = m_pIpBanTable[ui16IpTableIdx];
BanItem * curBan = NULL, * nextBan = nullptr;
while (next != NULL)
{
cur = next;
next = cur->m_pNext;
if (memcmp(cur->pFirstBan->m_ui128IpHash, m_ui128IpHash, 16) == 0)
{
nextBan = cur->pFirstBan;
while (nextBan != NULL)
{
curBan = nextBan;
nextBan = curBan->m_pHashIpTableNext;
if (((curBan->m_ui8Bits & BanManager::TEMP) == BanManager::TEMP) == true)
{
Rem(curBan);
delete curBan;
}
}
return;
}
}
}
//---------------------------------------------------------------------------
bool BanManager::RangeBan(const char * m_sIpFrom, const uint8_t * ui128FromIpHash, const char * m_sIpTo, const uint8_t * ui128ToIpHash, const char * sReason, const char * sBy, const bool bFull)
{
RangeBanItem * pRangeBan = new (std::nothrow) RangeBanItem();
if (pRangeBan == NULL)
{
AppendDebugLog("%s - [MEM] Cannot allocate pRangeBan in BanManager::RangeBan\n");
return false;
}
pRangeBan->m_ui8Bits |= PERM;
strcpy(pRangeBan->m_sIpFrom, m_sIpFrom);
memcpy(pRangeBan->m_ui128FromIpHash, ui128FromIpHash, 16);
strcpy(pRangeBan->m_sIpTo, m_sIpTo);
memcpy(pRangeBan->m_ui128ToIpHash, ui128ToIpHash, 16);
if (bFull == true)
{
pRangeBan->m_ui8Bits |= FULL;
}
RangeBanItem * curBan = NULL,
* nxtBan = m_pRangeBanListS;
// PPK ... don't add range ban if is already here same perm (full) range ban
while (nxtBan != NULL)
{
curBan = nxtBan;
nxtBan = curBan->m_pNext;
if (memcmp(curBan->m_ui128FromIpHash, pRangeBan->m_ui128FromIpHash, 16) != 0 ||
memcmp(curBan->m_ui128ToIpHash, pRangeBan->m_ui128ToIpHash, 16) != 0)
{
continue;
}
if ((curBan->m_ui8Bits & TEMP) == TEMP)
{
continue;
}
if (((curBan->m_ui8Bits & FULL) == FULL) == false && ((pRangeBan->m_ui8Bits & FULL) == FULL) == true)
{
RemRange(curBan);
delete curBan;
continue;
}
delete pRangeBan;
return false;
}
if (CreateReason(pRangeBan, sReason))
{
return false;
}
if (AddBanInternal(sBy, pRangeBan) == false)
{
return false;
}
AddRange(pRangeBan);
Save();
return true;
}
//---------------------------------------------------------------------------
bool BanManager::RangeTempBan(const char * m_sIpFrom, const uint8_t * ui128FromIpHash, const char * m_sIpTo, const uint8_t * ui128ToIpHash, const char * sReason, const char * sBy, const uint32_t minutes,
const time_t &expiretime, const bool bFull)
{
RangeBanItem * pRangeBan = new (std::nothrow) RangeBanItem();
if (pRangeBan == NULL)
{
AppendDebugLog("%s - [MEM] Cannot allocate pRangeBan in BanManager::RangeTempBan\n");
return false;
}
pRangeBan->m_ui8Bits |= TEMP;
strcpy(pRangeBan->m_sIpFrom, m_sIpFrom);
memcpy(pRangeBan->m_ui128FromIpHash, ui128FromIpHash, 16);
strcpy(pRangeBan->m_sIpTo, m_sIpTo);
memcpy(pRangeBan->m_ui128ToIpHash, ui128ToIpHash, 16);
if (bFull == true)
{
pRangeBan->m_ui8Bits |= FULL;
}
time_t acc_time;
time(&acc_time);
if (expiretime > 0)
{
pRangeBan->m_tTempBanExpire = expiretime;
}
else
{
if (minutes > 0)
{
pRangeBan->m_tTempBanExpire = acc_time + (minutes * 60);
}
else
{
pRangeBan->m_tTempBanExpire = acc_time + (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_DEFAULT_TEMP_BAN_TIME] * 60);
}
}
RangeBanItem * curBan = NULL,
* nxtBan = m_pRangeBanListS;
// PPK ... don't add range ban if is already here same perm (full) range ban or longer temp ban for same range
while (nxtBan != NULL)
{
curBan = nxtBan;
nxtBan = curBan->m_pNext;
if (memcmp(curBan->m_ui128FromIpHash, pRangeBan->m_ui128FromIpHash, 16) != 0 || memcmp(curBan->m_ui128ToIpHash, pRangeBan->m_ui128ToIpHash, 16) != 0)
{
continue;
}
if (((curBan->m_ui8Bits & TEMP) == TEMP) == true && curBan->m_tTempBanExpire < pRangeBan->m_tTempBanExpire)
{
if (((curBan->m_ui8Bits & FULL) == FULL) == false || ((pRangeBan->m_ui8Bits & FULL) == FULL) == true)
{
RemRange(curBan);
delete curBan;
continue;
}
continue;
}
if (((curBan->m_ui8Bits & FULL) == FULL) == false && ((pRangeBan->m_ui8Bits & FULL) == FULL) == true)
{
continue;
}
delete pRangeBan;
return false;
}
if (CreateReason(pRangeBan, sReason))
{
return false;
}
if (AddBanInternal(sBy, pRangeBan) == false)
{
return false;
}
AddRange(pRangeBan);
Save();
return true;
}
//---------------------------------------------------------------------------
bool BanManager::RangeUnban(const uint8_t * ui128FromIpHash, const uint8_t * ui128ToIpHash)
{
RangeBanItem * cur = NULL,
* next = m_pRangeBanListS;
while (next != NULL)
{
cur = next;
next = cur->m_pNext;
if (memcmp(cur->m_ui128FromIpHash, ui128FromIpHash, 16) == 0 && memcmp(cur->m_ui128ToIpHash, ui128ToIpHash, 16) == 0)
{
RemRange(cur);
delete cur;
return true;
}
}
Save();
return false;
}
//---------------------------------------------------------------------------
bool BanManager::RangeUnban(const uint8_t * ui128FromIpHash, const uint8_t * ui128ToIpHash, unsigned char cType)
{
RangeBanItem * cur = NULL,
* next = m_pRangeBanListS;
while (next != NULL)
{
cur = next;
next = cur->m_pNext;
if ((cur->m_ui8Bits & cType) == cType && memcmp(cur->m_ui128FromIpHash, ui128FromIpHash, 16) == 0 && memcmp(cur->m_ui128ToIpHash, ui128ToIpHash, 16) == 0)
{
RemRange(cur);
delete cur;
return true;
}
}
Save();
return false;
}
//---------------------------------------------------------------------------
↑ V1042 This file is marked with copyleft license, which requires you to open the derived source code.
↑ V557 Array overrun is possible. The '510' index is pointing beyond array bound.
↑ V557 Array overrun is possible. The '509' index is pointing beyond array bound.
↑ V557 Array overrun is possible. The '508' index is pointing beyond array bound.
↑ V557 Array overrun is possible. The '510' index is pointing beyond array bound.
↑ V557 Array overrun is possible. The '509' index is pointing beyond array bound.
↑ V557 Array overrun is possible. The '508' index is pointing beyond array bound.
↑ V1032 The pointer '"FI"' is cast to a more strictly aligned pointer type.
↑ V1032 The pointer '"FV"' is cast to a more strictly aligned pointer type.
↑ V1032 The pointer '"FI"' is cast to a more strictly aligned pointer type.
↑ V1032 The pointer '"FV"' is cast to a more strictly aligned pointer type.