/*
* PtokaX - hub server for Direct Connect peer to peer network.
* Copyright (C) 2002-2005 Ptaczek, Ptaczek at PtokaX dot org
* 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 "DcCommands.h"
//---------------------------------------------------------------------------
#include "colUsers.h"
#include "GlobalDataQueue.h"
#include "hashBanManager.h"
#include "hashRegManager.h"
#include "hashUsrManager.h"
#include "LanguageManager.h"
#include "LuaScriptManager.h"
#include "ProfileManager.h"
#include "ServerManager.h"
#include "SettingManager.h"
#include "UdpDebug.h"
#include "User.h"
#include "utility.h"
#include "ZlibUtility.h"
#ifdef USE_FLYLINKDC_EXT_JSON
#include "../json/json.hpp"
#include <algorithm>
#endif
//---------------------------------------------------------------------------
#ifdef _WIN32
#pragma hdrstop
#endif
//---------------------------------------------------------------------------
#include "DeFlood.h"
#include "HubCommands.h"
#include "IP2Country.h"
#include "ResNickManager.h"
#include "TextFileManager.h"
//---------------------------------------------------------------------------
#ifdef _BUILD_GUI
#include "../gui.win/GuiUtil.h"
#include "../gui.win/MainWindowPageUsersChat.h"
#endif
#ifdef _WITH_SQLITE
#include "DB-SQLite.h"
#elif _WITH_POSTGRES
#include "DB-PostgreSQL.h"
#elif _WITH_MYSQL
#include "DB-MySQL.h"
#endif
//---------------------------------------------------------------------------
DcCommands * DcCommands::m_Ptr = NULL;
//---------------------------------------------------------------------------
DcCommands::PassBf::PassBf(const uint8_t * ui128Hash) : m_pPrev(NULL), m_pNext(NULL), m_iCount(1)
{
m_ui128IpHash.init(ui128Hash);
}
//---------------------------------------------------------------------------
DcCommands::DcCommands() : m_pPasswdBfCheck(NULL), m_ui32StatChat(0), m_ui32StatCmdUnknown(0), m_ui32StatCmdTo(0), m_ui32StatCmdMyInfo(0), m_ui32StatCmdSearch(0), m_ui32StatCmdSR(0), m_ui32StatCmdRevCTM(0), m_ui32StatCmdOpForceMove(0), m_ui32StatCmdMyPass(0),
m_ui32StatCmdValidate(0), m_ui32StatCmdKey(0), m_ui32StatCmdGetInfo(0), m_ui32StatCmdGetNickList(0), m_ui32StatCmdConnectToMe(0), m_ui32StatCmdVersion(0), m_ui32StatCmdKick(0), m_ui32StatCmdSupports(0), m_ui32StatBotINFO(0), m_ui32StatZPipe(0), m_ui32StatCmdMultiSearch(0),
m_ui32StatCmdMultiConnectToMe(0), m_ui32StatCmdClose(0)
{
// ...
#ifdef USE_FLYLINKDC_EXT_JSON
m_iStatCmdExtJSON = 0;
#endif
}
//---------------------------------------------------------------------------
DcCommands::~DcCommands()
{
PassBf * cur = NULL,
* next = m_pPasswdBfCheck;
while (next != NULL)
{
cur = next;
next = cur->m_pNext;
delete cur;
}
m_pPasswdBfCheck = NULL;
}
//---------------------------------------------------------------------------
// Process DC data form User
void DcCommands::PreProcessData(DcCommand * pDcCommand)
{
#ifdef USE_FLYLINKDC_EXT_JSON
bool bCheck = true; // TODO
#endif
#ifdef _BUILD_GUI
// Full raw data trace for better logging
if (::SendMessage(MainWindowPageUsersChat::m_Ptr->m_hWndPageItems[MainWindowPageUsersChat::BTN_SHOW_COMMANDS], BM_GETCHECK, 0, 0) == BST_CHECKED)
{
int iMsgLen = snprintf(ServerManager::m_pGlobalBuffer, ServerManager::m_szGlobalBufferSize, "%s (%s) > ", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
if (iMsgLen > 0)
{
RichEditAppendText(MainWindowPageUsersChat::m_Ptr->m_hWndPageItems[MainWindowPageUsersChat::REDT_CHAT], (ServerManager::m_pGlobalBuffer + string(pDcCommand->m_sCommand, pDcCommand->m_ui32CommandLen)).c_str());
}
}
#endif
// micro spam
if (pDcCommand->m_ui32CommandLen < 5)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Garbage DATA from %s (%s) -> %s", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_sCommand);
pDcCommand->m_pUser->Close();
return;
}
if (pDcCommand->m_sCommand[0] == '$')
{
if(const auto l_end_command = strchr(pDcCommand->m_sCommand,' '))
{
const auto c = *l_end_command;
*l_end_command = 0x00;
GlobalDataQueue::m_Ptr->m_flylinkdc_hub_dc_commands_counter.Add({{"command", pDcCommand->m_sCommand}}).Increment();
*l_end_command = c;
}
}
static const uint32_t ui32ulti = *((uint32_t *)"ulti");
static const uint32_t ui32ick = *((uint32_t *)"ick ");
switch (pDcCommand->m_pUser->m_ui8State)
{
case User::STATE_SOCKET_ACCEPTED:
if (pDcCommand->m_sCommand[0] == '$')
{
if (memcmp(pDcCommand->m_sCommand + 1, "MyNick ", 7) == 0)
{
MyNick(pDcCommand);
return;
}
}
break;
case User::STATE_KEY_OR_SUP:
if (pDcCommand->m_sCommand[0] == '$')
{
if (memcmp(pDcCommand->m_sCommand + 1, "Supports ", 9) == 0)
{
m_ui32StatCmdSupports++;
Supports(pDcCommand);
return;
}
else if (*((uint32_t *)(pDcCommand->m_sCommand + 1)) == *((uint32_t *)"Key "))
{
m_ui32StatCmdKey++;
Key(pDcCommand);
return;
}
else if (memcmp(pDcCommand->m_sCommand + 1, "MyNick ", 7) == 0)
{
MyNick(pDcCommand);
return;
}
}
break;
case User::STATE_VALIDATE:
{
if (pDcCommand->m_sCommand[0] == '$')
{
switch (pDcCommand->m_sCommand[1])
{
case 'K':
if (memcmp(pDcCommand->m_sCommand + 2, "ey ", 3) == 0)
{
m_ui32StatCmdKey++;
if (((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_HAVE_SUPPORTS) == User::BIT_HAVE_SUPPORTS) == false)
{
Key(pDcCommand);
}
else
{
pDcCommand->m_pUser->FreeBuffer();
}
return;
}
break;
case 'V':
if (memcmp(pDcCommand->m_sCommand + 2, "alidateNick ", 12) == 0)
{
m_ui32StatCmdValidate++;
ValidateNick(pDcCommand);
return;
}
break;
#ifdef USE_FLYLINKDC_EXT_JSON
case 'E':
if (memcmp(pDcCommand->m_sCommand + 2, "xtJSON ", 7) == 0)
{
m_iStatCmdExtJSON++;
}
break;
#endif // USE_FLYLINKDC_EXT_JSON
case 'M':
if (memcmp(pDcCommand->m_sCommand + 2, "yINFO $ALL ", 11) == 0)
{
m_ui32StatCmdMyInfo++;
if (((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_QUICKLIST) == User::SUPPORTBIT_QUICKLIST) == false)
{
// bad state
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad state (%hhu) in $MyINFO %s (%s) - user closed.", pDcCommand->m_pUser->m_ui8State, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
if (MyINFODeflood(pDcCommand) == false)
{
return;
}
// PPK [ Strikes back ;) ] ... get nick from MyINFO
char *cTemp;
if ((cTemp = strchr(pDcCommand->m_sCommand + 13, ' ')) == NULL)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Attempt to validate empty nick from %s (%s) - user closed. (QuickList -> %s)", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_sCommand);
pDcCommand->m_pUser->Close();
return;
}
// PPK ... one null please :)
cTemp[0] = '\0';
if (ValidateUserNick(pDcCommand, pDcCommand->m_pUser, pDcCommand->m_sCommand + 13, (cTemp - pDcCommand->m_sCommand) - 13, false) == false) return;
cTemp[0] = ' ';
// 1st time MyINFO, user is being added to nicklist
if (MyINFO(pDcCommand) == false || (pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_WAITING_FOR_PASS) == User::BIT_WAITING_FOR_PASS ||
((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_PINGER) == User::BIT_PINGER) == true)
return;
pDcCommand->m_pUser->AddMeOrIPv4Check();
return;
}
break;
case 'G':
if (pDcCommand->m_ui32CommandLen == 13 && memcmp(pDcCommand->m_sCommand + 2, "etNickList", 10) == 0)
{
m_ui32StatCmdGetNickList++;
if (((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_QUICKLIST) == User::SUPPORTBIT_QUICKLIST) == false &&
((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_PINGER) == User::BIT_PINGER) == false)
{
// bad state
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad state (%hhu) in $GetNickList %s (%s) - user closed.", pDcCommand->m_pUser->m_ui8State, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
GetNickList(pDcCommand);
return;
}
break;
default:
break;
}
}
break;
}
case User::STATE_VERSION_OR_MYPASS:
{
if (pDcCommand->m_sCommand[0] == '$')
{
switch (pDcCommand->m_sCommand[1])
{
case 'V':
if (memcmp(pDcCommand->m_sCommand + 2, "ersion ", 7) == 0)
{
m_ui32StatCmdVersion++;
Version(pDcCommand);
return;
}
break;
case 'G':
if (pDcCommand->m_ui32CommandLen == 13 && memcmp(pDcCommand->m_sCommand + 2, "etNickList", 10) == 0)
{
m_ui32StatCmdGetNickList++;
if (GetNickList(pDcCommand) == true && ((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_QUICKLIST) == User::SUPPORTBIT_QUICKLIST) == false)
{
pDcCommand->m_pUser->m_ui32BoolBits |= User::BIT_GETNICKLIST;
}
return;
}
break;
#ifdef USE_FLYLINKDC_EXT_JSON
case 'E':
if (memcmp(pDcCommand->m_sCommand + 2, "xtJSON ", 7) == 0)
{
m_iStatCmdExtJSON++;
}
break;
#endif // USE_FLYLINKDC_EXT_JSON
case 'M':
if (pDcCommand->m_sCommand[2] == 'y')
{
if (memcmp(pDcCommand->m_sCommand + 3, "INFO $ALL ", 10) == 0)
{
m_ui32StatCmdMyInfo++;
if (MyINFODeflood(pDcCommand) == false)
{
return;
}
// Am I sending MyINFO of someone other ?
// OR i try to fuck up hub with some chars after my nick ??? ... PPK
if ((pDcCommand->m_sCommand[13 + pDcCommand->m_pUser->m_ui8NickLen] != ' ') || (memcmp(pDcCommand->m_pUser->m_sNick, pDcCommand->m_sCommand + 13, pDcCommand->m_pUser->m_ui8NickLen) != 0))
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Nick spoofing in myinfo from %s (%s) - user closed. (%s)", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_sCommand);
pDcCommand->m_pUser->Close();
return;
}
if (MyINFO(pDcCommand) == false || (pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_WAITING_FOR_PASS) == User::BIT_WAITING_FOR_PASS || ((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_PINGER) == User::BIT_PINGER) == true)
{
return;
}
pDcCommand->m_pUser->AddMeOrIPv4Check();
return;
}
else if (memcmp(pDcCommand->m_sCommand + 3, "Pass ", 5) == 0)
{
m_ui32StatCmdMyPass++;
MyPass(pDcCommand);
return;
}
}
break;
default:
break;
}
}
break;
}
case User::STATE_GETNICKLIST_OR_MYINFO:
{
if (pDcCommand->m_sCommand[0] == '$')
{
if (pDcCommand->m_ui32CommandLen == 13 && memcmp(pDcCommand->m_sCommand + 1, "GetNickList", 11) == 0)
{
m_ui32StatCmdGetNickList++;
if (GetNickList(pDcCommand) == true)
{
pDcCommand->m_pUser->m_ui32BoolBits |= User::BIT_GETNICKLIST;
}
return;
}
else if (memcmp(pDcCommand->m_sCommand + 1, "MyINFO $ALL ", 12) == 0)
{
m_ui32StatCmdMyInfo++;
if (MyINFODeflood(pDcCommand) == false)
{
return;
}
// Am I sending MyINFO of someone other ?
// OR i try to fuck up hub with some chars after my nick ??? ... PPK
if ((pDcCommand->m_sCommand[13 + pDcCommand->m_pUser->m_ui8NickLen] != ' ') || (memcmp(pDcCommand->m_pUser->m_sNick, pDcCommand->m_sCommand + 13, pDcCommand->m_pUser->m_ui8NickLen) != 0))
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Nick spoofing in myinfo from %s (%s) - user closed. (%s)", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_sCommand);
pDcCommand->m_pUser->Close();
return;
}
if (MyINFO(pDcCommand) == false || (pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_WAITING_FOR_PASS) == User::BIT_WAITING_FOR_PASS ||
((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_PINGER) == User::BIT_PINGER) == true)
return;
pDcCommand->m_pUser->AddMeOrIPv4Check();
return;
}
#ifdef USE_FLYLINKDC_EXT_JSON
else if (memcmp(pDcCommand->m_sCommand + 1, "ExtJSON ", 8) == 0)
{
m_iStatCmdExtJSON++;
}
#endif // USE_FLYLINKDC_EXT_JSON
}
break;
}
case User::STATE_IPV4_CHECK:
case User::STATE_ADDME:
case User::STATE_ADDME_1LOOP:
{
if (pDcCommand->m_sCommand[0] == '$')
{
if(const auto l_end_command = strchr(pDcCommand->m_sCommand,' '))
{
const auto c = *l_end_command;
*l_end_command = 0x00;
GlobalDataQueue::m_Ptr->m_flylinkdc_hub_dc_commands_counter.Add({{"command", pDcCommand->m_sCommand}}).Increment();
*l_end_command = c;
}
switch (pDcCommand->m_sCommand[1])
{
case 'G':
if (pDcCommand->m_ui32CommandLen == 13 && memcmp(pDcCommand->m_sCommand + 2, "etNickList", 10) == 0)
{
m_ui32StatCmdGetNickList++;
if (GetNickList(pDcCommand) == true)
{
pDcCommand->m_pUser->m_ui32BoolBits |= User::BIT_GETNICKLIST;
}
return;
}
break;
#ifdef USE_FLYLINKDC_EXT_JSON
case 'E':
if (memcmp(pDcCommand->m_sCommand + 2, "xtJSON ", 7) == 0)
{
m_iStatCmdExtJSON++; // ExtJSON Step 1 First Login
if (ExtJSONDeflood(pDcCommand->m_pUser, pDcCommand->m_sCommand, pDcCommand->m_ui32CommandLen, bCheck) == false)
{
return;
}
{
//using json = nlohmann::json;
const auto l_pos_json = strchr(pDcCommand->m_sCommand + 10, ' ');
std::string l_json_str;
std::string l_nick;
if (l_pos_json)
{
const int l_len_header = l_pos_json - pDcCommand->m_sCommand;
l_json_str = std::string(l_pos_json, pDcCommand->m_ui32CommandLen - l_len_header);
l_nick = std::string(pDcCommand->m_sCommand, l_len_header);
if (l_json_str.size() > 3 && l_json_str[l_json_str.size() - 1] == '|' && l_json_str[l_json_str.size() - 2] == '}')
{
l_json_str = l_json_str.substr(0, l_json_str.size() - 1);
for (auto i = l_json_str.begin(); i != l_json_str.end(); ++i)
{
if ((unsigned char)(*i) >= 0x80)
{
*i = '.';
}
}
}
}
try
{
auto l_json = nlohmann::json::parse(l_json_str);
}
catch (const std::exception& e)
{
pDcCommand->m_pUser->m_is_invalid_json = true;
pDcCommand->m_pUser->logInvalidUser(-1, pDcCommand->m_sCommand, pDcCommand->m_ui32CommandLen, false);
printf("Error parse JSON: IP = %s JSON: %s Len = %u error = %s\r\n",
pDcCommand->m_pUser->m_sIP, l_nick.c_str(), pDcCommand->m_ui32CommandLen, e.what());
#ifndef _WIN32
syslog(LOG_NOTICE, "Error parse JSON: IP = %s JSON: %s Len = %u error = %s", pDcCommand->m_pUser->m_sIP, l_nick.c_str(), pDcCommand->m_ui32CommandLen, e.what());
#endif
UdpDebug::m_Ptr->BroadcastFormat("Error parse JSON: IP = %s JSON: %s Len = %u error = %s\r\n", pDcCommand->m_pUser->m_sIP, l_nick.c_str(), pDcCommand->m_ui32CommandLen, e.what());
pDcCommand->m_pUser->Close();
return;
}
}
pDcCommand->m_pUser->initExtJSON(pDcCommand->m_sCommand);
#ifdef USE_FLYLINKDC_EXT_JSON
ScriptManager::m_Ptr->Arrival(pDcCommand, ScriptManager::EXTJSON_ARRIVAL);
#endif
}
break;
#endif // USE_FLYLINKDC_EXT_JSON
case 'M':
{
if (memcmp(pDcCommand->m_sCommand + 2, "yINFO $ALL ", 11) == 0)
{
m_ui32StatCmdMyInfo++;
if (MyINFODeflood(pDcCommand) == false)
{
return;
}
// Am I sending MyINFO of someone other ?
// OR i try to fuck up hub with some chars after my nick ??? ... PPK
if ((pDcCommand->m_sCommand[13 + pDcCommand->m_pUser->m_ui8NickLen] != ' ') || (memcmp(pDcCommand->m_pUser->m_sNick, pDcCommand->m_sCommand + 13, pDcCommand->m_pUser->m_ui8NickLen) != 0))
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Nick spoofing in myinfo from %s (%s) - user closed. (%s)", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_sCommand);
pDcCommand->m_pUser->Close();
return;
}
MyINFO(pDcCommand);
return;
}
else if (memcmp(pDcCommand->m_sCommand + 2, "ultiSearch ", 11) == 0)
{
m_ui32StatCmdMultiSearch++;
SearchDeflood(pDcCommand, true);
return;
}
break;
}
case 'S':
if (memcmp(pDcCommand->m_sCommand + 2, "earch ", 6) == 0)
{
m_ui32StatCmdSearch++;
SearchDeflood(pDcCommand, false);
return;
}
break;
default:
break;
}
}
else if (pDcCommand->m_sCommand[0] == '<')
{
m_ui32StatChat++;
ChatDeflood(pDcCommand);
return;
}
break;
}
case User::STATE_ADDED:
{
if (pDcCommand->m_sCommand[0] == '$')
{
switch (pDcCommand->m_sCommand[1])
{
case 'S':
{
if (memcmp(pDcCommand->m_sCommand + 2, "earch ", 6) == 0)
{
m_ui32StatCmdSearch++;
if (SearchDeflood(pDcCommand, false) == true)
{
Search(pDcCommand, false);
}
return;
}
else if (*((uint16_t *)(pDcCommand->m_sCommand + 2)) == *((uint16_t *)"R "))
{
m_ui32StatCmdSR++;
SR(pDcCommand);
return;
}
break;
}
case 'C':
if (memcmp(pDcCommand->m_sCommand + 2, "onnectToMe ", 11) == 0)
{
m_ui32StatCmdConnectToMe++;
ConnectToMe(pDcCommand, false);
return;
}
else if (memcmp(pDcCommand->m_sCommand + 2, "lose ", 5) == 0)
{
m_ui32StatCmdClose++;
Close(pDcCommand);
return;
}
break;
case 'R':
if (memcmp(pDcCommand->m_sCommand + 2, "evConnectToMe ", 14) == 0)
{
m_ui32StatCmdRevCTM++;
RevConnectToMe(pDcCommand);
return;
}
break;
#ifdef USE_FLYLINKDC_EXT_JSON
case 'E':
if (memcmp(pDcCommand->m_sCommand + 2, "xtJSON ", 7) == 0)
{
m_iStatCmdExtJSON++; // ExtJSON Step 3 - Change ExtJSON
if (ExtJSONDeflood(pDcCommand->m_pUser, pDcCommand->m_sCommand, pDcCommand->m_ui32CommandLen, bCheck) == false)
{
return;
}
SetExtJSON(pDcCommand->m_pUser, pDcCommand->m_sCommand, pDcCommand->m_ui32CommandLen);
return;
}
break;
#endif // USE_FLYLINKDC_EXT_JSON
case 'M':
if (memcmp(pDcCommand->m_sCommand + 2, "yINFO $ALL ", 11) == 0)
{
m_ui32StatCmdMyInfo++;
if (MyINFODeflood(pDcCommand) == false)
{
return;
}
// Am I sending MyINFO of someone other ?
// OR i try to fuck up hub with some chars after my nick ??? ... PPK
if ((pDcCommand->m_sCommand[13 + pDcCommand->m_pUser->m_ui8NickLen] != ' ') || (memcmp(pDcCommand->m_pUser->m_sNick, pDcCommand->m_sCommand + 13, pDcCommand->m_pUser->m_ui8NickLen) != 0))
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Nick spoofing in myinfo from %s (%s) - user closed. (%s)", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_sCommand);
pDcCommand->m_pUser->Close();
return;
}
if (MyINFO(pDcCommand) == true)
{
pDcCommand->m_pUser->m_ui32BoolBits |= User::BIT_PRCSD_MYINFO;
}
return;
}
else if (*((uint32_t *)(pDcCommand->m_sCommand + 2)) == ui32ulti)
{
if (memcmp(pDcCommand->m_sCommand + 6, "Search ", 7) == 0)
{
m_ui32StatCmdMultiSearch++;
if (SearchDeflood(pDcCommand, true) == true)
{
Search(pDcCommand, true);
}
return;
}
else if (memcmp(pDcCommand->m_sCommand + 6, "ConnectToMe ", 12) == 0)
{
m_ui32StatCmdMultiConnectToMe++;
ConnectToMe(pDcCommand, true);
return;
}
}
else if (memcmp(pDcCommand->m_sCommand + 2, "yPass ", 6) == 0)
{
m_ui32StatCmdMyPass++;
//MyPass(pUser, sData, ui32Len);
if ((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_WAITING_FOR_PASS) == User::BIT_WAITING_FOR_PASS)
{
pDcCommand->m_pUser->m_ui32BoolBits &= ~User::BIT_WAITING_FOR_PASS;
if (pDcCommand->m_pUser->m_LogInOut.m_pBuffer != NULL)
{
int iProfile = ProfileManager::m_Ptr->GetProfileIndex(pDcCommand->m_pUser->m_LogInOut.m_pBuffer);
if (iProfile == -1)
{
pDcCommand->m_pUser->SendFormat("DcCommands::PreProcessData::MyPass->RegUser1", true, "<%s> %s.|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_ERR_NO_PROFILE_GIVEN_NAME_EXIST]);
delete pDcCommand->m_pUser->m_LogInOut.m_pBuffer;
pDcCommand->m_pUser->m_LogInOut.m_pBuffer = NULL;
return;
}
if (pDcCommand->m_ui32CommandLen < 10)
{
pDcCommand->m_pUser->SendFormat("DcCommands::PreProcessData::MyPass->RegUser2", true, "<%s> %s!|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_PASS_MUST_SPECIFIED]);
pDcCommand->m_pUser->m_ui32BoolBits |= User::BIT_WAITING_FOR_PASS;
return;
}
if (pDcCommand->m_ui32CommandLen > 73)
{
pDcCommand->m_pUser->SendFormat("DcCommands::PreProcessData::MyPass->RegUser2-1", true, "<%s> %s!|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_MAX_ALWD_PASS_LEN_64_CHARS]);
pDcCommand->m_pUser->m_ui32BoolBits |= User::BIT_WAITING_FOR_PASS;
return;
}
pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - 1] = '\0'; // cutoff pipe
if (RegManager::m_Ptr->AddNew(pDcCommand->m_pUser->m_sNick, pDcCommand->m_sCommand + 8, (uint16_t)iProfile) == false)
{
pDcCommand->m_pUser->SendFormat("DcCommands::PreProcessData::MyPass->RegUser3", true, "<%s> %s.|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_SORRY_YOU_ARE_ALREADY_REGISTERED]);
}
else
{
pDcCommand->m_pUser->SendFormat("DcCommands::PreProcessData::MyPass->RegUser4", true, "<%s> %s %s.|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_THANK_YOU_FOR_PASSWORD_YOU_ARE_NOW_REGISTERED_AS],
pDcCommand->m_pUser->m_LogInOut.m_pBuffer);
}
delete pDcCommand->m_pUser->m_LogInOut.m_pBuffer;
pDcCommand->m_pUser->m_LogInOut.m_pBuffer = NULL;
pDcCommand->m_pUser->m_i32Profile = iProfile;
if (((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_OPERATOR) == User::BIT_OPERATOR) == false)
{
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::HASKEYICON) == false)
{
return;
}
pDcCommand->m_pUser->m_ui32BoolBits |= User::BIT_OPERATOR;
// alex82 ... HideUserKey / ������ ���� �����
if (((pDcCommand->m_pUser->m_ui32InfoBits & User::INFOBIT_HIDE_KEY) == User::INFOBIT_HIDE_KEY) == false)
{
Users::m_Ptr->Add2OpList(pDcCommand->m_pUser);
GlobalDataQueue::m_Ptr->OpListStore(pDcCommand->m_pUser->m_sNick);
}
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::ALLOWEDOPCHAT) == true)
{
if (SettingManager::m_Ptr->m_bBools[SETBOOL_REG_OP_CHAT] == true &&
(SettingManager::m_Ptr->m_bBools[SETBOOL_REG_BOT] == false || SettingManager::m_Ptr->m_bBotsSameNick == false))
{
if (((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_NOHELLO) == User::SUPPORTBIT_NOHELLO) == false)
{
pDcCommand->m_pUser->SendCharDelayed(SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_OP_CHAT_HELLO],
SettingManager::m_Ptr->m_ui16PreTextsLens[SettingManager::SETPRETXT_OP_CHAT_HELLO]);
}
pDcCommand->m_pUser->SendCharDelayed(SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_OP_CHAT_MYINFO], SettingManager::m_Ptr->m_ui16PreTextsLens[SettingManager::SETPRETXT_OP_CHAT_MYINFO]);
pDcCommand->m_pUser->SendFormat("DcCommands::PreProcessData::MyPass->RegUser5", true, "$OpList %s$$|", SettingManager::m_Ptr->m_sTexts[SETTXT_OP_CHAT_NICK]);
}
}
}
}
return;
}
}
break;
case 'G':
{
if (pDcCommand->m_ui32CommandLen == 13 && memcmp(pDcCommand->m_sCommand + 2, "etNickList", 10) == 0)
{
m_ui32StatCmdGetNickList++;
if (GetNickList(pDcCommand) == true)
{
pDcCommand->m_pUser->m_ui32BoolBits |= User::BIT_GETNICKLIST;
}
return;
}
else if (memcmp(pDcCommand->m_sCommand + 2, "etINFO ", 7) == 0)
{
m_ui32StatCmdGetInfo++;
GetINFO(pDcCommand);
return;
}
break;
}
case 'T':
if (memcmp(pDcCommand->m_sCommand + 2, "o: ", 3) == 0)
{
m_ui32StatCmdTo++;
To(pDcCommand);
return;
}
break;
case 'K':
if (*((uint32_t *)(pDcCommand->m_sCommand + 2)) == ui32ick)
{
m_ui32StatCmdKick++;
Kick(pDcCommand);
return;
}
break;
case 'O':
if (memcmp(pDcCommand->m_sCommand + 2, "pForceMove $Who:", 16) == 0)
{
m_ui32StatCmdOpForceMove++;
OpForceMove(pDcCommand);
return;
}
break;
default:
break;
}
}
else if (pDcCommand->m_sCommand[0] == '<')
{
m_ui32StatChat++;
if (ChatDeflood(pDcCommand) == true)
{
Chat(pDcCommand);
}
return;
}
break;
}
case User::STATE_CLOSING:
case User::STATE_REMME:
return;
}
// PPK ... fallback to full command identification and disconnect on bad state or unknown command not handled by script
switch (pDcCommand->m_sCommand[0])
{
case '$':
switch (pDcCommand->m_sCommand[1])
{
case 'B':
{
if (memcmp(pDcCommand->m_sCommand + 2, "otINFO", 6) == 0)
{
m_ui32StatBotINFO++;
BotINFO(pDcCommand);
return;
}
break;
}
case 'C':
if (memcmp(pDcCommand->m_sCommand + 2, "onnectToMe ", 11) == 0)
{
m_ui32StatCmdConnectToMe++;
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad state (%hhu) in $ConnectToMe %s (%s) - user closed.", pDcCommand->m_pUser->m_ui8State, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
else if (memcmp(pDcCommand->m_sCommand + 2, "lose ", 5) == 0)
{
m_ui32StatCmdClose++;
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad state (%hhu) in $Close %s (%s) - user closed.", pDcCommand->m_pUser->m_ui8State, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
break;
case 'G':
{
if (*((uint16_t *)(pDcCommand->m_sCommand + 2)) == *((uint16_t *)"et"))
{
if (memcmp(pDcCommand->m_sCommand + 4, "INFO ", 5) == 0)
{
m_ui32StatCmdGetInfo++;
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad state (%hhu) in $GetINFO %s (%s) - user closed.", pDcCommand->m_pUser->m_ui8State, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
else if (pDcCommand->m_ui32CommandLen == 13 && *((uint64_t *)(pDcCommand->m_sCommand + 4)) == *((uint64_t *)"NickList"))
{
m_ui32StatCmdGetNickList++;
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad state (%hhu) in $GetNickList %s (%s) - user closed.", pDcCommand->m_pUser->m_ui8State, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
}
break;
}
case 'K':
if (memcmp(pDcCommand->m_sCommand + 2, "ey ", 3) == 0)
{
m_ui32StatCmdKey++;
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad state (%hhu) in $Key %s (%s) - user closed.", pDcCommand->m_pUser->m_ui8State, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
else if (*((uint32_t *)(pDcCommand->m_sCommand + 2)) == ui32ick)
{
m_ui32StatCmdKick++;
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad state (%hhu) in $Kick %s (%s) - user closed.", pDcCommand->m_pUser->m_ui8State, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
break;
#ifdef USE_FLYLINKDC_EXT_JSON
case 'E':
if (memcmp(pDcCommand->m_sCommand + 2, "xtJSON ", 7) == 0)
{
#ifdef _DBG
int iret = sprintf(msg, "%s (%s) bad state in case $ExtJSON: %d", pUser->Nick, pUser->IP, pUser->m_iState);
if (CheckSprintf(iret, 1024, "DcCommands::PreProcessData56") == true)
{
Memo(msg);
}
#endif
// pUser->m_ui32BoolBits |= User::BIT_PRCSD_EXT_JSON;
m_iStatCmdExtJSON++; // ExtJSON Step 2 (After Login)
// TODO ExtJSON ?? UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad state (%d) in $ExtJSON %s (%s) - user closed.", (int)pUser->m_ui8State, pUser->m_sNick, pUser->m_sIP);
// curUser->Close();
return;
}
break;
#endif // USE_FLYLINKDC_EXT_JSON
case 'M':
if (*((uint32_t *)(pDcCommand->m_sCommand + 2)) == ui32ulti)
{
if (memcmp(pDcCommand->m_sCommand + 6, "ConnectToMe ", 12) == 0)
{
m_ui32StatCmdMultiConnectToMe++;
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad state (%hhu) in $MultiConnectToMe %s (%s) - user closed.", pDcCommand->m_pUser->m_ui8State, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
else if (memcmp(pDcCommand->m_sCommand + 6, "Search ", 7) == 0)
{
m_ui32StatCmdMultiSearch++;
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad state (%hhu) in $MultiSearch %s (%s) - user closed.", pDcCommand->m_pUser->m_ui8State, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
}
else if (pDcCommand->m_sCommand[2] == 'y')
{
if (memcmp(pDcCommand->m_sCommand + 3, "INFO $ALL ", 10) == 0)
{
m_ui32StatCmdMyInfo++;
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad state (%hhu) in $MyINFO %s (%s) - user closed.", pDcCommand->m_pUser->m_ui8State, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
else if (memcmp(pDcCommand->m_sCommand + 3, "Pass ", 5) == 0)
{
m_ui32StatCmdMyPass++;
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad state (%hhu) in $MyPass %s (%s) - user closed.", pDcCommand->m_pUser->m_ui8State, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
}
break;
case 'O':
if (memcmp(pDcCommand->m_sCommand + 2, "pForceMove $Who:", 16) == 0)
{
m_ui32StatCmdOpForceMove++;
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad state (%hhu) in $OpForceMove %s (%s) - user closed.", pDcCommand->m_pUser->m_ui8State, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
break;
case 'R':
if (memcmp(pDcCommand->m_sCommand + 2, "evConnectToMe ", 14) == 0)
{
m_ui32StatCmdRevCTM++;
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad state (%hhu) in $RevConnectToMe %s (%s) - user closed.", pDcCommand->m_pUser->m_ui8State, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
break;
case 'S':
switch (pDcCommand->m_sCommand[2])
{
case 'e':
{
if (memcmp(pDcCommand->m_sCommand + 3, "arch ", 5) == 0)
{
m_ui32StatCmdSearch++;
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad state (%hhu) in $Search %s (%s) - user closed.", pDcCommand->m_pUser->m_ui8State, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
break;
}
case 'R':
if (pDcCommand->m_sCommand[3] == ' ')
{
m_ui32StatCmdSR++;
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad state (%hhu) in $SR %s (%s) - user closed.", pDcCommand->m_pUser->m_ui8State, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
break;
case 'u':
{
if (memcmp(pDcCommand->m_sCommand + 3, "pports ", 7) == 0)
{
m_ui32StatCmdSupports++;
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad state (%hhu) in $Supports %s (%s) - user closed.", pDcCommand->m_pUser->m_ui8State, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
break;
}
default:
break;
}
break;
case 'T':
if (memcmp(pDcCommand->m_sCommand + 2, "o: ", 3) == 0)
{
m_ui32StatCmdTo++;
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad state (%hhu) in $To %s (%s) - user closed.", pDcCommand->m_pUser->m_ui8State, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
break;
case 'V':
if (memcmp(pDcCommand->m_sCommand + 2, "alidateNick ", 12) == 0)
{
m_ui32StatCmdValidate++;
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad state (%hhu) in $ValidateNick %s (%s) - user closed.", pDcCommand->m_pUser->m_ui8State, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
else if (memcmp(pDcCommand->m_sCommand + 2, "ersion ", 7) == 0)
{
m_ui32StatCmdVersion++;
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad state (%hhu) in $Version %s (%s) - user closed.", pDcCommand->m_pUser->m_ui8State, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
break;
default:
break;
}
break;
case '<':
{
m_ui32StatChat++;
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad state (%hhu) in Chat %s (%s) - user closed.", pDcCommand->m_pUser->m_ui8State, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
default:
break;
}
Unknown(pDcCommand);
}
//---------------------------------------------------------------------------
// $BotINFO pinger identification|
void DcCommands::BotINFO(DcCommand * pDcCommand)
{
if (((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_PINGER) == User::BIT_PINGER) == false || ((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_HAVE_BOTINFO) == User::BIT_HAVE_BOTINFO) == true)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Not pinger $BotINFO or $BotINFO flood from %s (%s)", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
if (pDcCommand->m_ui32CommandLen < 9)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad $BotINFO (%s) from %s (%s) - user closed.", pDcCommand->m_sCommand, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
pDcCommand->m_pUser->m_ui32BoolBits |= User::BIT_HAVE_BOTINFO;
if (ScriptManager::m_Ptr->Arrival(pDcCommand, ScriptManager::BOTINFO_ARRIVAL) == true ||
pDcCommand->m_pUser->m_ui8State >= User::STATE_CLOSING)
{
return;
}
pDcCommand->m_pUser->SendFormat("DcCommands::BotINFO", true, "$HubINFO %s$%s:%hu$%s.px.$%hd$%" PRIu64 "$%hd$%hd$PtokaX$%s|", SettingManager::m_Ptr->m_sTexts[SETTXT_HUB_NAME], SettingManager::m_Ptr->m_sTexts[SETTXT_HUB_ADDRESS], SettingManager::m_Ptr->m_ui16PortNumbers[0],
SettingManager::m_Ptr->m_sTexts[SETTXT_HUB_DESCRIPTION] == NULL ? "" : SettingManager::m_Ptr->m_sTexts[SETTXT_HUB_DESCRIPTION], SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_USERS], SettingManager::m_Ptr->m_ui64MinShare, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MIN_SLOTS_LIMIT],
SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_HUBS_LIMIT], SettingManager::m_Ptr->m_sTexts[SETTXT_HUB_OWNER_EMAIL] == NULL ? "" : SettingManager::m_Ptr->m_sTexts[SETTXT_HUB_OWNER_EMAIL]);
if (((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_HAVE_GETNICKLIST) == User::BIT_HAVE_GETNICKLIST) == true)
{
pDcCommand->m_pUser->Close();
}
}
//---------------------------------------------------------------------------
// $ConnectToMe <nickname> <ownip>:<ownlistenport>
// $MultiConnectToMe <nick> <ownip:port> <hub[:port]>
void DcCommands::ConnectToMe(DcCommand * pDcCommand, const bool bMulti)
{
if ((bMulti == false && pDcCommand->m_ui32CommandLen < 23) || (bMulti == true && pDcCommand->m_ui32CommandLen < 28))
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad $%sConnectToMe (%s) from %s (%s) - user closed.", bMulti == false ? "" : "Multi", pDcCommand->m_sCommand, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
// PPK ... check flood ...
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::NODEFLOODCTM) == false)
{
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_CTM_ACTION] != 0)
{
if (DeFloodCheckForFlood(pDcCommand->m_pUser, DEFLOOD_CTM, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_CTM_ACTION],
pDcCommand->m_pUser->m_ui16CTMs, pDcCommand->m_pUser->m_ui64CTMsTick, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_CTM_MESSAGES],
(uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_CTM_TIME]) == true)
{
return;
}
}
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_CTM_ACTION2] != 0)
{
if (DeFloodCheckForFlood(pDcCommand->m_pUser, DEFLOOD_CTM, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_CTM_ACTION2],
pDcCommand->m_pUser->m_ui16CTMs2, pDcCommand->m_pUser->m_ui64CTMsTick2, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_CTM_MESSAGES2],
(uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_CTM_TIME2]) == true)
{
return;
}
}
}
if (pDcCommand->m_ui32CommandLen > (uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_CTM_LEN])
{
pDcCommand->m_pUser->SendFormat("DcCommands::ConnectToMe", true, "<%s> %s!|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_CTM_TOO_LONG]);
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Long $ConnectToMe from %s (%s) - user closed. (%s)", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_sCommand);
pDcCommand->m_pUser->Close();
return;
}
// PPK ... $CTM means user is active ?!? Probably yes, let set it active and use on another places ;)
if (pDcCommand->m_pUser->m_sTag == NULL)
{
pDcCommand->m_pUser->m_ui32BoolBits |= User::BIT_IPV4_ACTIVE;
}
// full data only and allow blocking
if (ScriptManager::m_Ptr->Arrival(pDcCommand, (uint8_t)(bMulti == false ? ScriptManager::CONNECTTOME_ARRIVAL : ScriptManager::MULTICONNECTTOME_ARRIVAL)) == true ||
pDcCommand->m_pUser->m_ui8State >= User::STATE_CLOSING)
{
return;
}
char * pSpace = strchr(pDcCommand->m_sCommand + (bMulti == false ? 13 : 18), ' ');
if (pSpace == NULL)
{
return;
}
pSpace[0] = '\0';
User * pOtherUser = HashManager::m_Ptr->FindUser(pDcCommand->m_sCommand + (bMulti == false ? 13 : 18), pSpace - (pDcCommand->m_sCommand + (bMulti == false ? 13 : 18)));
// PPK ... no connection to yourself !!!
if (pOtherUser == NULL || pOtherUser == pDcCommand->m_pUser || pOtherUser->m_ui8State != User::STATE_ADDED)
{
return;
}
pSpace[0] = ' ';
// IP check
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::NOIPCHECK) == false)
{
// At end of sData is | and we need to remove it.
pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - 1] = '\0';
// Now between pSpace+1 and end of string is something that should be IP:Port .. let's check that and start with length.
uint32_t ui32IpPortLen = (uint32_t)((pDcCommand->m_ui32CommandLen - 1) - ((pSpace + 1) - pDcCommand->m_sCommand));
// Check minimal (shortest ip:port can be [::1]:1) and maximal (longest ip:port can be [1234:1234:1234:1234:1234:1234:1234:1234]:12345S) length.
if (ui32IpPortLen < 7 || ui32IpPortLen > 48)
{
pDcCommand->m_pUser->SendFormat("DcCommands::ConnectToMe bad IP:Port len", true, "<%s> %s '%s'!|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_YOUR_CLIENT_SEND_INCORRECT_IPPORT_IN_COMMAND], pSpace + 1);
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad IP:Port length in %sCTM from %s (%s). (%s)", bMulti == false ? "" : "M", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_sCommand);
pDcCommand->m_pUser->m_is_bad_len_port = true; // FlylinkDC++
//pDcCommand->m_pUser->Close(); // FlylinkDC++
return;
}
// Check if Port is valid. Here can be S (as secure [what a joke lol]) to indicate TLS connection request after port ...
uint32_t ui32PortLen = 0;
uint16_t ui16Port = 0; // Zero == invalid port ...
bool bSecure = false; // To restore secure status after checks
if (((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_TLS2) == User::SUPPORTBIT_TLS2) == true && pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - 2] == 'S')
{
// Remove S character and set secure to true
pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - 2] = '\0';
bSecure = true;
// Check for port validity and get Port when valid
ui16Port = CheckAndGetPort(pSpace + 1 + (ui32IpPortLen - 7), (uint8_t)(ui32IpPortLen - ((pSpace + (ui32IpPortLen - 6)) - pSpace)), ui32PortLen);
}
else
{
// Check for port validity and get Port when valid
ui16Port = CheckAndGetPort(pSpace + 1 + (ui32IpPortLen - 6), (uint8_t)(ui32IpPortLen - ((pSpace + (ui32IpPortLen - 6)) - pSpace)), ui32PortLen);
}
// Check if we get valid port number
if (ui16Port == 0)
{
pDcCommand->m_pUser->SendFormat("DcCommands::ConnectToMe invalid Port", true, "<%s> %s '%s'!|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_YOUR_CLIENT_SEND_INCORRECT_PORT_IN_CTM], pSpace + 1);
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad Port in %sCTM from %s (%s). (%s)", bMulti == false ? "" : "M", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_sCommand);
pDcCommand->m_pUser->Close();
return;
}
uint32_t ui32IpLen = (ui32IpPortLen - ui32PortLen) - 1;
if (bSecure == true)
{
ui32IpLen--;
}
bool bInvalidIP = true;
char * pIP = pSpace + 1;
// Check if we get valid IP address
if ((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_IPV6) == User::BIT_IPV6)
{
if ((pDcCommand->m_pUser->m_ui8IpLen + 2U) == ui32IpLen && pIP[0] == '[' && pIP[1 + pDcCommand->m_pUser->m_ui8IpLen] == ']' && strncmp(pIP + 1, pDcCommand->m_pUser->m_sIP, pDcCommand->m_pUser->m_ui8IpLen) == 0)
{
bInvalidIP = false;
}
else if (((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_IPV4) == User::BIT_IPV4) && pDcCommand->m_pUser->m_ui8IPv4Len == ui32IpLen && strncmp(pIP, pDcCommand->m_pUser->m_sIPv4, pDcCommand->m_pUser->m_ui8IPv4Len) == 0)
{
bInvalidIP = false;
}
}
else if (pDcCommand->m_pUser->m_ui8IpLen == ui32IpLen && strncmp(pIP, pDcCommand->m_pUser->m_sIP, pDcCommand->m_pUser->m_ui8IpLen) == 0)
{
bInvalidIP = false;
}
if (bInvalidIP == true)
{
if (((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_WARNED_WRONG_IP) == User::BIT_WARNED_WRONG_IP) == false)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad Ip in %sCTM from %s (%s/%s). (%s)", bMulti == false ? "" : "M", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_pUser->m_sIPv4, pDcCommand->m_sCommand);
}
if ((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_IPV6) == User::BIT_IPV6 && (pOtherUser->m_ui32BoolBits & User::BIT_IPV6) == User::BIT_IPV6)
{
int iMsgLen = snprintf(ServerManager::m_pGlobalBuffer, ServerManager::m_szGlobalBufferSize, "$ConnectToMe %s [%s]:%hu%s|", pOtherUser->m_sNick, pDcCommand->m_pUser->m_sIP, ui16Port, bSecure == true ? "S" : "");
if (iMsgLen > 0)
{
pDcCommand->m_pUser->AddPrcsdCmd(PrcsdUsrCmd::CTM_MCTM_RCTM_SR_TO, ServerManager::m_pGlobalBuffer, iMsgLen, pOtherUser);
}
}
else if ((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_IPV4) == User::BIT_IPV4 && (pOtherUser->m_ui32BoolBits & User::BIT_IPV4) == User::BIT_IPV4)
{
char * sIP = pDcCommand->m_pUser->m_ui8IPv4Len == 0 ? pDcCommand->m_pUser->m_sIP : pDcCommand->m_pUser->m_sIPv4;
int iMsgLen = snprintf(ServerManager::m_pGlobalBuffer, ServerManager::m_szGlobalBufferSize, "$ConnectToMe %s %s:%hu%s|", pOtherUser->m_sNick, sIP, ui16Port, bSecure == true ? "S" : "");
if (iMsgLen > 0)
{
pDcCommand->m_pUser->AddPrcsdCmd(PrcsdUsrCmd::CTM_MCTM_RCTM_SR_TO, ServerManager::m_pGlobalBuffer, iMsgLen, pOtherUser);
}
}
if (ui32IpLen != 0 && pIP[ui32IpLen - 1] == ']')
{
pIP[ui32IpLen - 1] = '\0';
}
else
{
pIP[ui32IpLen] = '\0';
}
if (pIP[0] == '[')
{
pIP++;
}
SendIPFixedMsg(pDcCommand->m_pUser, pIP, pDcCommand->m_pUser->m_sIP);
return;
}
else
{
if (bSecure == true)
{
pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - 2] = 'S';
}
pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - 1] = '|';
}
}
if (bMulti == true)
{
pDcCommand->m_sCommand[5] = '$';
}
pDcCommand->m_pUser->AddPrcsdCmd(PrcsdUsrCmd::CTM_MCTM_RCTM_SR_TO, bMulti == false ? pDcCommand->m_sCommand : pDcCommand->m_sCommand + 5, bMulti == false ? pDcCommand->m_ui32CommandLen : pDcCommand->m_ui32CommandLen - 5, pOtherUser);
}
//---------------------------------------------------------------------------
// $GetINFO <nickname> <ownnickname>
void DcCommands::GetINFO(DcCommand * pDcCommand)
{
if (((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_NOGETINFO) == User::SUPPORTBIT_NOGETINFO) == true || ((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_NOHELLO) == User::SUPPORTBIT_NOHELLO) == true || ((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_QUICKLIST) == User::SUPPORTBIT_QUICKLIST) == true)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Not allowed user %s (%s) send $GetINFO - user closed.", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
// PPK ... code change, added own nick and space on right place check
if (pDcCommand->m_ui32CommandLen < (12u + pDcCommand->m_pUser->m_ui8NickLen) || pDcCommand->m_ui32CommandLen > (75u + pDcCommand->m_pUser->m_ui8NickLen) || pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - pDcCommand->m_pUser->m_ui8NickLen - 2] != ' ' ||
memcmp(pDcCommand->m_sCommand + (pDcCommand->m_ui32CommandLen - pDcCommand->m_pUser->m_ui8NickLen - 1), pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_ui8NickLen) != 0)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad $GetINFO from %s (%s) - user closed. (%s)", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_sCommand);
pDcCommand->m_pUser->Close();
return;
}
if (ScriptManager::m_Ptr->Arrival(pDcCommand, ScriptManager::GETINFO_ARRIVAL) == true ||
pDcCommand->m_pUser->m_ui8State >= User::STATE_CLOSING)
{
return;
}
}
//---------------------------------------------------------------------------
// $GetNickList
bool DcCommands::GetNickList(DcCommand * pDcCommand)
{
if (((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_QUICKLIST) == User::SUPPORTBIT_QUICKLIST) == true &&
((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_HAVE_GETNICKLIST) == User::BIT_HAVE_GETNICKLIST) == true)
{
// PPK ... refresh not allowed !
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad $GetNickList request %s (%s) - user closed.", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return false;
}
else if (((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_PINGER) == User::BIT_PINGER) == true)
{
if (((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_HAVE_GETNICKLIST) == User::BIT_HAVE_GETNICKLIST) == false)
{
pDcCommand->m_pUser->m_ui32BoolBits |= User::BIT_BIG_SEND_BUFFER;
if (((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_NOHELLO) == User::SUPPORTBIT_NOHELLO) == false && Users::m_Ptr->m_ui32NickListLen > 11)
{
if (((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_ZPIPE) == User::SUPPORTBIT_ZPIPE) == false)
{
pDcCommand->m_pUser->SendCharDelayed(Users::m_Ptr->m_pNickList, Users::m_Ptr->m_ui32NickListLen);
}
else
{
if (Users::m_Ptr->m_ui32ZNickListLen == 0)
{
Users::m_Ptr->m_pZNickList = ZlibUtility::m_Ptr->CreateZPipe(Users::m_Ptr->m_pNickList, Users::m_Ptr->m_ui32NickListLen, Users::m_Ptr->m_pZNickList,
Users::m_Ptr->m_ui32ZNickListLen, Users::m_Ptr->m_ui32ZNickListSize);
if (Users::m_Ptr->m_ui32ZNickListLen == 0)
{
pDcCommand->m_pUser->SendCharDelayed(Users::m_Ptr->m_pNickList, Users::m_Ptr->m_ui32NickListLen);
}
else
{
pDcCommand->m_pUser->PutInSendBuf(Users::m_Ptr->m_pZNickList, Users::m_Ptr->m_ui32ZNickListLen);
ServerManager::m_ui64BytesSentSaved += Users::m_Ptr->m_ui32NickListLen - Users::m_Ptr->m_ui32ZNickListLen;
}
}
else
{
pDcCommand->m_pUser->PutInSendBuf(Users::m_Ptr->m_pZNickList, Users::m_Ptr->m_ui32ZNickListLen);
ServerManager::m_ui64BytesSentSaved += Users::m_Ptr->m_ui32NickListLen - Users::m_Ptr->m_ui32ZNickListLen;
}
}
}
if (SettingManager::m_Ptr->m_ui8FullMyINFOOption == 2)
{
if (Users::m_Ptr->m_ui32MyInfosLen != 0)
{
if (((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_ZPIPE) == User::SUPPORTBIT_ZPIPE) == false)
{
pDcCommand->m_pUser->SendCharDelayed(Users::m_Ptr->m_pMyInfos, Users::m_Ptr->m_ui32MyInfosLen);
}
else
{
if (Users::m_Ptr->m_ui32ZMyInfosLen == 0)
{
Users::m_Ptr->m_pZMyInfos = ZlibUtility::m_Ptr->CreateZPipe(Users::m_Ptr->m_pMyInfos, Users::m_Ptr->m_ui32MyInfosLen, Users::m_Ptr->m_pZMyInfos,
Users::m_Ptr->m_ui32ZMyInfosLen, Users::m_Ptr->m_ui32ZMyInfosSize);
if (Users::m_Ptr->m_ui32ZMyInfosLen == 0)
{
pDcCommand->m_pUser->SendCharDelayed(Users::m_Ptr->m_pMyInfos, Users::m_Ptr->m_ui32MyInfosLen);
}
else
{
pDcCommand->m_pUser->PutInSendBuf(Users::m_Ptr->m_pZMyInfos, Users::m_Ptr->m_ui32ZMyInfosLen);
ServerManager::m_ui64BytesSentSaved += Users::m_Ptr->m_ui32MyInfosLen - Users::m_Ptr->m_ui32ZMyInfosLen;
}
}
else
{
pDcCommand->m_pUser->PutInSendBuf(Users::m_Ptr->m_pZMyInfos, Users::m_Ptr->m_ui32ZMyInfosLen);
ServerManager::m_ui64BytesSentSaved += Users::m_Ptr->m_ui32MyInfosLen - Users::m_Ptr->m_ui32ZMyInfosLen;
}
}
}
}
else if (Users::m_Ptr->m_ui32MyInfosTagLen != 0)
{
if (((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_ZPIPE) == User::SUPPORTBIT_ZPIPE) == false)
{
pDcCommand->m_pUser->SendCharDelayed(Users::m_Ptr->m_pMyInfosTag, Users::m_Ptr->m_ui32MyInfosTagLen);
}
else
{
if (Users::m_Ptr->m_ui32ZMyInfosTagLen == 0)
{
Users::m_Ptr->m_pZMyInfosTag = ZlibUtility::m_Ptr->CreateZPipe(Users::m_Ptr->m_pMyInfosTag, Users::m_Ptr->m_ui32MyInfosTagLen, Users::m_Ptr->m_pZMyInfosTag,
Users::m_Ptr->m_ui32ZMyInfosTagLen, Users::m_Ptr->m_ui32ZMyInfosTagSize);
if (Users::m_Ptr->m_ui32ZMyInfosTagLen == 0)
{
pDcCommand->m_pUser->SendCharDelayed(Users::m_Ptr->m_pMyInfosTag, Users::m_Ptr->m_ui32MyInfosTagLen);
}
else
{
pDcCommand->m_pUser->PutInSendBuf(Users::m_Ptr->m_pZMyInfosTag, Users::m_Ptr->m_ui32ZMyInfosTagLen);
ServerManager::m_ui64BytesSentSaved += Users::m_Ptr->m_ui32MyInfosTagLen - Users::m_Ptr->m_ui32ZMyInfosTagLen;
}
}
else
{
pDcCommand->m_pUser->PutInSendBuf(Users::m_Ptr->m_pZMyInfosTag, Users::m_Ptr->m_ui32ZMyInfosTagLen);
ServerManager::m_ui64BytesSentSaved += Users::m_Ptr->m_ui32MyInfosTagLen - Users::m_Ptr->m_ui32ZMyInfosTagLen;
}
}
}
if (Users::m_Ptr->m_ui32OpListLen > 9)
{
if (((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_ZPIPE) == User::SUPPORTBIT_ZPIPE) == false)
{
pDcCommand->m_pUser->SendCharDelayed(Users::m_Ptr->m_pOpList, Users::m_Ptr->m_ui32OpListLen);
}
else
{
if (Users::m_Ptr->m_ui32ZOpListLen == 0)
{
Users::m_Ptr->m_pZOpList = ZlibUtility::m_Ptr->CreateZPipe(Users::m_Ptr->m_pOpList, Users::m_Ptr->m_ui32OpListLen, Users::m_Ptr->m_pZOpList,
Users::m_Ptr->m_ui32ZOpListLen, Users::m_Ptr->m_ui32ZOpListSize);
if (Users::m_Ptr->m_ui32ZOpListLen == 0)
{
pDcCommand->m_pUser->SendCharDelayed(Users::m_Ptr->m_pOpList, Users::m_Ptr->m_ui32OpListLen);
}
else
{
pDcCommand->m_pUser->PutInSendBuf(Users::m_Ptr->m_pZOpList, Users::m_Ptr->m_ui32ZOpListLen);
ServerManager::m_ui64BytesSentSaved += Users::m_Ptr->m_ui32OpListLen - Users::m_Ptr->m_ui32ZOpListLen;
}
}
else
{
pDcCommand->m_pUser->PutInSendBuf(Users::m_Ptr->m_pZOpList, Users::m_Ptr->m_ui32ZOpListLen);
ServerManager::m_ui64BytesSentSaved += Users::m_Ptr->m_ui32OpListLen - Users::m_Ptr->m_ui32ZOpListLen;
}
}
}
if (pDcCommand->m_pUser->m_ui32SendBufDataLen != 0)
{
pDcCommand->m_pUser->Try2Send();
}
pDcCommand->m_pUser->m_ui32BoolBits |= User::BIT_HAVE_GETNICKLIST;
if (SettingManager::m_Ptr->m_bBools[SETBOOL_REPORT_PINGERS] == true)
{
GlobalDataQueue::m_Ptr->StatusMessageFormat("DcCommands::GetNickList", "<%s> *** %s: %s %s: %s %s.|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_PINGER_FROM_IP], pDcCommand->m_pUser->m_sIP,
LanguageManager::m_Ptr->m_sTexts[LAN_WITH_NICK], pDcCommand->m_pUser->m_sNick, LanguageManager::m_Ptr->m_sTexts[LAN_DETECTED_LWR]);
}
if (((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_HAVE_BOTINFO) == User::BIT_HAVE_BOTINFO) == true)
{
pDcCommand->m_pUser->Close();
}
return false;
}
else
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] $GetNickList flood from pinger %s (%s) - user closed.", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return false;
}
}
pDcCommand->m_pUser->m_ui32BoolBits |= User::BIT_HAVE_GETNICKLIST;
// PPK ... check flood...
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::NODEFLOODGETNICKLIST) == false &&
SettingManager::m_Ptr->m_i16Shorts[SETSHORT_GETNICKLIST_ACTION] != 0)
{
if (DeFloodCheckForFlood(pDcCommand->m_pUser, DEFLOOD_GETNICKLIST, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_GETNICKLIST_ACTION],
pDcCommand->m_pUser->m_ui16GetNickLists, pDcCommand->m_pUser->m_ui64GetNickListsTick, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_GETNICKLIST_MESSAGES],
((uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_GETNICKLIST_TIME]) * 60) == true)
{
return false;
}
}
if (ScriptManager::m_Ptr->Arrival(pDcCommand, ScriptManager::GETNICKLIST_ARRIVAL) == true ||
pDcCommand->m_pUser->m_ui8State >= User::STATE_CLOSING ||
((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_QUICKLIST) == User::SUPPORTBIT_QUICKLIST) == true)
{
return false;
}
return true;
}
//---------------------------------------------------------------------------
// $Key
void DcCommands::Key(DcCommand * pDcCommand)
{
if (((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_HAVE_KEY) == User::BIT_HAVE_KEY) == true)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] $Key flood from %s (%s) - user closed.", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
pDcCommand->m_pUser->m_ui32BoolBits |= User::BIT_HAVE_KEY;
pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - 1] = '\0'; // cutoff pipe
if (pDcCommand->m_ui32CommandLen < 6 || strcmp(Lock2Key(pDcCommand->m_pUser->m_LogInOut.m_pBuffer), pDcCommand->m_sCommand + 5) != 0)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad $Key from %s (%s) - user closed. (%s)", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_sCommand);
pDcCommand->m_pUser->Close();
return;
}
pDcCommand->m_pUser->FreeBuffer();
pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - 1] = '|'; // add back pipe
ScriptManager::m_Ptr->Arrival(pDcCommand, ScriptManager::KEY_ARRIVAL);
if (pDcCommand->m_pUser->m_ui8State >= User::STATE_CLOSING)
{
return;
}
pDcCommand->m_pUser->m_ui8State = User::STATE_VALIDATE;
}
//---------------------------------------------------------------------------
// $Kick <name>
void DcCommands::Kick(DcCommand * pDcCommand)
{
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::KICK) == false)
{
pDcCommand->m_pUser->SendFormat("DcCommands::Kick1", true, "<%s> %s!|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_YOU_ARE_NOT_ALWD_TO_USE_THIS_CMD]);
return;
}
if (pDcCommand->m_ui32CommandLen < 8)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad $Kick (%s) from %s (%s) - user closed.", pDcCommand->m_sCommand, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
if (ScriptManager::m_Ptr->Arrival(pDcCommand, ScriptManager::KICK_ARRIVAL) == true || pDcCommand->m_pUser->m_ui8State >= User::STATE_CLOSING)
{
return;
}
pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - 1] = '\0'; // cutoff pipe
User *OtherUser = HashManager::m_Ptr->FindUser(pDcCommand->m_sCommand + 6, pDcCommand->m_ui32CommandLen - 7);
if (OtherUser != NULL)
{
// Self-kick
if (OtherUser == pDcCommand->m_pUser)
{
pDcCommand->m_pUser->SendFormat("DcCommands::Kick2", true, "<%s> %s!|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_YOU_CANT_KICK_YOURSELF]);
return;
}
if (OtherUser->m_i32Profile != -1 && pDcCommand->m_pUser->m_i32Profile > OtherUser->m_i32Profile)
{
pDcCommand->m_pUser->SendFormat("DcCommands::Kick3", true, "<%s> %s %s!|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_YOU_ARE_NOT_ALLOWED_TO_KICK], OtherUser->m_sNick);
return;
}
if (pDcCommand->m_pUser->m_pCmdToUserStrt != NULL)
{
PrcsdToUsrCmd * cur = NULL, * prev = NULL,
* next = pDcCommand->m_pUser->m_pCmdToUserStrt;
while (next != NULL)
{
cur = next;
next = cur->m_pNext;
if (OtherUser == cur->m_pToUser)
{
cur->m_pToUser->SendChar(cur->m_sCommand, cur->m_ui32Len);
if (prev == NULL)
{
if (cur->m_pNext == NULL)
{
pDcCommand->m_pUser->m_pCmdToUserStrt = NULL;
pDcCommand->m_pUser->m_pCmdToUserEnd = NULL;
}
else
{
pDcCommand->m_pUser->m_pCmdToUserStrt = cur->m_pNext;
}
}
else if (cur->m_pNext == NULL)
{
prev->m_pNext = NULL;
pDcCommand->m_pUser->m_pCmdToUserEnd = prev;
}
else
{
prev->m_pNext = cur->m_pNext;
}
safe_free(cur->m_sCommand);
delete cur;
break;
}
prev = cur;
}
}
char * sBanTime;
if (OtherUser->m_LogInOut.m_pBuffer != NULL &&
(sBanTime = stristr(OtherUser->m_LogInOut.m_pBuffer, "_BAN_")) != NULL)
{
sBanTime[0] = '\0';
if (sBanTime[5] == '\0' || sBanTime[5] == ' ') // permban
{
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::BAN) == false)
{
pDcCommand->m_pUser->SendFormat("DcCommands::Kick4", true, "<%s> %s!|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_YOU_ARE_NOT_ALWD_TO_USE_THIS_CMD]);
return;
}
BanManager::m_Ptr->Ban(OtherUser, OtherUser->m_LogInOut.m_pBuffer, pDcCommand->m_pUser->m_sNick, false);
GlobalDataQueue::m_Ptr->StatusMessageFormat("DcCommands::Kick1", "<%s> *** %s %s %s %s %s %s %s.|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], OtherUser->m_sNick, LanguageManager::m_Ptr->m_sTexts[LAN_WITH_IP], OtherUser->m_sIP, LanguageManager::m_Ptr->m_sTexts[LAN_HAS_BEEN],
LanguageManager::m_Ptr->m_sTexts[LAN_BANNED_LWR], LanguageManager::m_Ptr->m_sTexts[LAN_BY_LWR], pDcCommand->m_pUser->m_sNick);
if (SettingManager::m_Ptr->m_bBools[SETBOOL_SEND_STATUS_MESSAGES] == false || ((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_OPERATOR) == User::BIT_OPERATOR) == false)
{
pDcCommand->m_pUser->SendFormat("DcCommands::Kick5", true, "<%s> *** %s %s %s %s %s.|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], OtherUser->m_sNick, LanguageManager::m_Ptr->m_sTexts[LAN_WITH_IP], OtherUser->m_sIP, LanguageManager::m_Ptr->m_sTexts[LAN_HAS_BEEN],
LanguageManager::m_Ptr->m_sTexts[LAN_BANNED_LWR]);
}
// disconnect the user
UdpDebug::m_Ptr->BroadcastFormat("[SYS] User %s (%s) kicked by %s", OtherUser->m_sNick, OtherUser->m_sIP, pDcCommand->m_pUser->m_sNick);
OtherUser->Close();
return;
}
else if (isdigit(sBanTime[5]) != 0) // tempban
{
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::TEMP_BAN) == false)
{
pDcCommand->m_pUser->SendFormat("DcCommands::Kick6", true, "<%s> %s!|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_YOU_ARE_NOT_ALWD_TO_USE_THIS_CMD]);
return;
}
uint32_t i = 6;
while (sBanTime[i] != '\0' && isdigit(sBanTime[i]) != 0)
{
i++;
}
char cTime = sBanTime[i];
sBanTime[i] = '\0';
int iTime = atoi(sBanTime + 5);
time_t acc_time, ban_time;
if (cTime != '\0' && iTime > 0 && GenerateTempBanTime(cTime, iTime, acc_time, ban_time) == true)
{
BanManager::m_Ptr->TempBan(OtherUser, OtherUser->m_LogInOut.m_pBuffer, pDcCommand->m_pUser->m_sNick, 0, ban_time, false);
static char sTime[256];
strcpy(sTime, formatTime((ban_time - acc_time) / 60));
GlobalDataQueue::m_Ptr->StatusMessageFormat("DcCommands::Kick2", "<%s> *** %s %s %s %s %s %s %s %s: %s.|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], OtherUser->m_sNick, LanguageManager::m_Ptr->m_sTexts[LAN_WITH_IP], OtherUser->m_sIP, LanguageManager::m_Ptr->m_sTexts[LAN_HAS_BEEN],
LanguageManager::m_Ptr->m_sTexts[LAN_TEMP_BANNED], LanguageManager::m_Ptr->m_sTexts[LAN_BY_LWR], pDcCommand->m_pUser->m_sNick, LanguageManager::m_Ptr->m_sTexts[LAN_TO_LWR], sTime);
if (SettingManager::m_Ptr->m_bBools[SETBOOL_SEND_STATUS_MESSAGES] == false || ((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_OPERATOR) == User::BIT_OPERATOR) == false)
{
pDcCommand->m_pUser->SendFormat("DcCommands::Kick7", true, "<%s> *** %s %s %s %s %s %s: %s.|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], OtherUser->m_sNick, LanguageManager::m_Ptr->m_sTexts[LAN_WITH_IP], OtherUser->m_sIP, LanguageManager::m_Ptr->m_sTexts[LAN_HAS_BEEN],
LanguageManager::m_Ptr->m_sTexts[LAN_TEMP_BANNED], LanguageManager::m_Ptr->m_sTexts[LAN_TO_LWR], sTime);
}
// disconnect the user
UdpDebug::m_Ptr->BroadcastFormat("[SYS] User %s (%s) kicked by %s", OtherUser->m_sNick, OtherUser->m_sIP, pDcCommand->m_pUser->m_sNick);
OtherUser->Close();
return;
}
}
}
BanManager::m_Ptr->TempBan(OtherUser, OtherUser->m_LogInOut.m_pBuffer != NULL ? OtherUser->m_LogInOut.m_pBuffer : NULL, pDcCommand->m_pUser->m_sNick, 0, 0, false);
GlobalDataQueue::m_Ptr->StatusMessageFormat("DcCommands::Kick3", "<%s> *** %s %s %s %s %s.|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], OtherUser->m_sNick, LanguageManager::m_Ptr->m_sTexts[LAN_WITH_IP], OtherUser->m_sIP,
LanguageManager::m_Ptr->m_sTexts[LAN_WAS_KICKED_BY], pDcCommand->m_pUser->m_sNick);
if (SettingManager::m_Ptr->m_bBools[SETBOOL_SEND_STATUS_MESSAGES] == false || ((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_OPERATOR) == User::BIT_OPERATOR) == false)
{
pDcCommand->m_pUser->SendFormat("DcCommands::Kick8", true, "<%s> *** %s %s %s %s.|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], OtherUser->m_sNick, LanguageManager::m_Ptr->m_sTexts[LAN_WITH_IP], OtherUser->m_sIP, LanguageManager::m_Ptr->m_sTexts[LAN_WAS_KICKED]);
}
// disconnect the user
UdpDebug::m_Ptr->BroadcastFormat("[SYS] User %s (%s) kicked by %s", OtherUser->m_sNick, OtherUser->m_sIP, pDcCommand->m_pUser->m_sNick);
OtherUser->Close();
}
}
//---------------------------------------------------------------------------
// $Search $MultiSearch
bool DcCommands::SearchDeflood(DcCommand * pDcCommand, const bool bMulti)
{
// search flood protection ... modified by PPK ;-)
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::NODEFLOODSEARCH) == false)
{
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SEARCH_ACTION] != 0)
{
if (DeFloodCheckForFlood(pDcCommand->m_pUser, DEFLOOD_SEARCH, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SEARCH_ACTION],
pDcCommand->m_pUser->m_ui16Searchs, pDcCommand->m_pUser->m_ui64SearchsTick, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SEARCH_MESSAGES],
(uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SEARCH_TIME]) == true)
{
return false;
}
}
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SEARCH_ACTION2] != 0)
{
if (DeFloodCheckForFlood(pDcCommand->m_pUser, DEFLOOD_SEARCH, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SEARCH_ACTION2],
pDcCommand->m_pUser->m_ui16Searchs2, pDcCommand->m_pUser->m_ui64SearchsTick2, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SEARCH_MESSAGES2],
(uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SEARCH_TIME2]) == true)
{
return false;
}
}
// 2nd check for same search flood
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SAME_SEARCH_ACTION] != 0)
{
bool bNewData = false;
if (DeFloodCheckForSameFlood(pDcCommand->m_pUser, DEFLOOD_SAME_SEARCH, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SAME_SEARCH_ACTION],
pDcCommand->m_pUser->m_ui16SameSearchs, pDcCommand->m_pUser->m_ui64SameSearchsTick,
SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SAME_SEARCH_MESSAGES], SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SAME_SEARCH_TIME],
pDcCommand->m_sCommand + (bMulti == true ? 13 : 8), pDcCommand->m_ui32CommandLen - (bMulti == true ? 13 : 8),
pDcCommand->m_pUser->m_sLastSearch, pDcCommand->m_pUser->m_ui16LastSearchLen, bNewData) == true)
{
return false;
}
if (bNewData == true)
{
pDcCommand->m_pUser->SetLastSearch(pDcCommand->m_sCommand + (bMulti == true ? 13 : 8), pDcCommand->m_ui32CommandLen - (bMulti == true ? 13 : 8));
}
}
}
return true;
}
//---------------------------------------------------------------------------
// $Search $MultiSearch
void DcCommands::Search(DcCommand * pDcCommand, const bool bMulti)
{
#ifdef _WIN32
#ifdef _PtokaX_TESTING_
// std::string l_ddos = "$Search :000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 ????MNBFJPTUDG|";
// std::string l_ddos = "$Search 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064185F?F?0?1?0431765961|";
//std::string l_ddos = "$Search 127.0.0.1:\\://185.61.138.193:411 F?F?0?1?M|";
//sData = (char *) l_ddos.data();
//ui32Len = strlen(sData);
#endif
#endif
uint32_t iAfterCmd;
if (bMulti == false)
{
if (pDcCommand->m_ui32CommandLen < 10
|| pDcCommand->m_ui32CommandLen > 512) // FlylinkDC++
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad $Search (%s) from %s (%s) - user closed.", pDcCommand->m_sCommand, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
iAfterCmd = 8;
}
else
{
if (pDcCommand->m_ui32CommandLen < 15
|| pDcCommand->m_ui32CommandLen > 512) // FlylinkDC++
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad $MultiSearch (%s) from %s (%s) - user closed.", pDcCommand->m_sCommand, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
iAfterCmd = 13;
}
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::NOSEARCHINTERVAL) == false)
{
if (DeFloodCheckInterval(pDcCommand->m_pUser, INTERVAL_SEARCH, pDcCommand->m_pUser->m_ui16SearchsInt,
pDcCommand->m_pUser->m_ui64SearchsIntTick, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SEARCH_INTERVAL_MESSAGES],
(uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SEARCH_INTERVAL_TIME]) == true)
{
return;
}
}
if (ScriptManager::m_Ptr->Arrival(pDcCommand, ScriptManager::SEARCH_ARRIVAL) == true ||
pDcCommand->m_pUser->m_ui8State >= User::STATE_CLOSING)
{
return;
}
// send search from actives to all, from passives to actives only
// PPK ... optimization ;o)
if (bMulti == false && *((uint32_t *)(pDcCommand->m_sCommand + iAfterCmd)) == *((uint32_t *)"Hub:"))
{
if (pDcCommand->m_pUser->m_sTag == NULL)
{
pDcCommand->m_pUser->m_ui32BoolBits &= ~User::BIT_IPV4_ACTIVE;
}
// PPK ... check nick !!!
if ((pDcCommand->m_sCommand[iAfterCmd + 4 + pDcCommand->m_pUser->m_ui8NickLen] != ' ') || (memcmp(pDcCommand->m_sCommand + iAfterCmd + 4, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_ui8NickLen) != 0))
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Nick spoofing in search from %s (%s) - user closed. (%s)", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_sCommand);
pDcCommand->m_pUser->Close();
return;
}
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::NOSEARCHLIMITS) == false &&
(SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MIN_SEARCH_LEN] != 0 || SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_SEARCH_LEN] != 0))
{
// PPK ... search string len check
// $Search Hub:PPK F?T?0?2?test|
uint32_t iChar = iAfterCmd + 8 + pDcCommand->m_pUser->m_ui8NickLen + 1;
uint32_t iCount = 0;
for (; iChar < pDcCommand->m_ui32CommandLen; iChar++)
{
if (pDcCommand->m_sCommand[iChar] == '?')
{
iCount++;
if (iCount == 2)
break;
}
}
iCount = pDcCommand->m_ui32CommandLen - 2 - iChar;
if (iCount < (uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MIN_SEARCH_LEN])
{
pDcCommand->m_pUser->SendFormat("DcCommands::Search1", true, "<%s> %s %hd.|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_SORRY_MIN_SEARCH_LEN_IS], SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MIN_SEARCH_LEN]);
return;
}
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_SEARCH_LEN] != 0 && iCount > (uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_SEARCH_LEN])
{
pDcCommand->m_pUser->SendFormat("DcCommands::Search2", true, "<%s> %s %hd.|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_SORRY_MAX_SEARCH_LEN_IS], SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_SEARCH_LEN]);
return;
}
}
pDcCommand->m_pUser->m_ui32SR = 0;
pDcCommand->m_pUser->m_pCmdPassiveSearch = AddSearch(pDcCommand->m_pUser, pDcCommand->m_pUser->m_pCmdPassiveSearch, pDcCommand->m_sCommand, pDcCommand->m_ui32CommandLen, false);
}
else
{
if (pDcCommand->m_pUser->m_sTag == NULL)
{
pDcCommand->m_pUser->m_ui32BoolBits |= User::BIT_IPV4_ACTIVE;
}
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::NOSEARCHLIMITS) == false && (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MIN_SEARCH_LEN] != 0 || SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_SEARCH_LEN] != 0))
{
// PPK ... search string len check
// $Search 1.2.3.4:1 F?F?0?2?test| / $Search [::1]:1 F?F?0?2?test|
uint32_t ui32Char = iAfterCmd + 9;
uint32_t ui32QCount = 0;
for (; ui32Char < pDcCommand->m_ui32CommandLen; ui32Char++)
{
if (pDcCommand->m_sCommand[ui32Char] == '?')
{
ui32QCount++;
if (ui32QCount == 4)
break;
}
}
uint32_t ui32Count = pDcCommand->m_ui32CommandLen - 2 - ui32Char;
if (ui32QCount != 4 || ui32Count < (uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MIN_SEARCH_LEN])
{
pDcCommand->m_pUser->SendFormat("DcCommands::Search3", true, "<%s> %s %hd.|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_SORRY_MIN_SEARCH_LEN_IS], SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MIN_SEARCH_LEN]);
return;
}
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_SEARCH_LEN] != 0 && ui32Count > (uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_SEARCH_LEN])
{
pDcCommand->m_pUser->SendFormat("DcCommands::Search4", true, "<%s> %s %hd.|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_SORRY_MAX_SEARCH_LEN_IS], SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_SEARCH_LEN]);
return;
}
}
// Get space after IP:Port
char * pSpace = strchr(pDcCommand->m_sCommand + iAfterCmd, ' ');
if (pSpace == NULL)
{
return;
}
pSpace[0] = '\0';
// Now we have between sData+iAfterCmd and pSpace IP:Port ... or we should have. Let's check that and start with length.
uint32_t ui32IpPortLen = (uint32_t)(pSpace - (pDcCommand->m_sCommand + iAfterCmd));
// Check minimal (shortest ip:port can be [::1]:1) and maximal (longest ip:port can be [1234:1234:1234:1234:1234:1234:1234:1234]:12345S) length.
if (ui32IpPortLen < 7 || ui32IpPortLen > 48)
{
pDcCommand->m_pUser->SendFormat("DcCommands::Search bad IP:Port len", true, "<%s> %s '%s'!|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_YOUR_CLIENT_SEND_INCORRECT_IPPORT_IN_COMMAND], pDcCommand->m_sCommand + iAfterCmd);
pSpace[0] = ' ';
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad IP:Port length in %sSearch from %s (%s). (%s)", bMulti == false ? "" : "M", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_sCommand);
pDcCommand->m_pUser->m_is_bad_port = true; // FlylinkDC++
//pDcCommand->m_pUser->Close();
return;
}
// Check if Port is valid.
uint32_t ui32PortLen = 0;
uint16_t ui16Port = 0; // Zero == invalid port ...
// Check for port validity and get Port when valid
ui16Port = CheckAndGetPort(pDcCommand->m_sCommand + iAfterCmd + (ui32IpPortLen - 6), (uint8_t)(ui32IpPortLen - (((pDcCommand->m_sCommand + iAfterCmd) + (ui32IpPortLen - 6)) - (pDcCommand->m_sCommand + iAfterCmd))), ui32PortLen);
// Check if we get valid port number
if (ui16Port == 0)
{
pDcCommand->m_pUser->SendFormat("DcCommands::Search invalid Port", true, "<%s> %s '%s'!|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_YOUR_CLIENT_SEND_INCORRECT_PORT_IN_SEARCH], pDcCommand->m_sCommand + iAfterCmd);
pSpace[0] = ' ';
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad Port in %sSearch from %s (%s). (%s)", bMulti == false ? "" : "M", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_sCommand);
pDcCommand->m_pUser->Close();
return;
}
uint32_t ui32IpLen = (ui32IpPortLen - ui32PortLen) - 1;
bool bInvalidIP = true;
char * pIP = pDcCommand->m_sCommand + iAfterCmd;
// Check if we get valid IP address
if ((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_IPV6) == User::BIT_IPV6)
{
if ((pDcCommand->m_pUser->m_ui8IpLen + 2U) == ui32IpLen && pIP[0] == '[' && pIP[1 + pDcCommand->m_pUser->m_ui8IpLen] == ']' && strncmp(pIP + 1, pDcCommand->m_pUser->m_sIP, pDcCommand->m_pUser->m_ui8IpLen) == 0)
{
bInvalidIP = false;
}
else if (((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_IPV4) == User::BIT_IPV4) && pDcCommand->m_pUser->m_ui8IPv4Len == ui32IpLen && strncmp(pIP, pDcCommand->m_pUser->m_sIPv4, pDcCommand->m_pUser->m_ui8IPv4Len) == 0)
{
bInvalidIP = false;
}
}
else if (pDcCommand->m_pUser->m_ui8IpLen == ui32IpLen && strncmp(pIP, pDcCommand->m_pUser->m_sIP, pDcCommand->m_pUser->m_ui8IpLen) == 0)
{
bInvalidIP = false;
}
// IP check
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::NOIPCHECK) == false && bInvalidIP == true)
{
if (((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_WARNED_WRONG_IP) == User::BIT_WARNED_WRONG_IP) == false)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad Ip in %sSearch from %s (%s/%s). (%s)", bMulti == false ? "" : "M", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_pUser->m_sIPv4, pDcCommand->m_sCommand);
}
if ((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_IPV6) == User::BIT_IPV6)
{
if ((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_IPV6_ACTIVE) == User::BIT_IPV6_ACTIVE)
{
int iMsgLen = snprintf(ServerManager::m_pGlobalBuffer, ServerManager::m_szGlobalBufferSize, "$Search [%s]:%hu %s", pDcCommand->m_pUser->m_sIP, ui16Port, pSpace + 1);
if (iMsgLen > 0)
{
pDcCommand->m_pUser->m_pCmdActive6Search = AddSearch(pDcCommand->m_pUser, pDcCommand->m_pUser->m_pCmdActive6Search, ServerManager::m_pGlobalBuffer, iMsgLen, true);
}
}
else
{
int iMsgLen = snprintf(ServerManager::m_pGlobalBuffer, ServerManager::m_szGlobalBufferSize, "$Search Hub:%s %s", pDcCommand->m_pUser->m_sNick, pSpace + 1);
if (iMsgLen > 0)
{
pDcCommand->m_pUser->m_pCmdPassiveSearch = AddSearch(pDcCommand->m_pUser, pDcCommand->m_pUser->m_pCmdPassiveSearch, ServerManager::m_pGlobalBuffer, iMsgLen, false);
}
}
if ((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_IPV4) == User::BIT_IPV4)
{
if ((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_IPV4_ACTIVE) == User::BIT_IPV4_ACTIVE)
{
int iMsgLen = snprintf(ServerManager::m_pGlobalBuffer, ServerManager::m_szGlobalBufferSize, "$Search %s:%hu %s", pDcCommand->m_pUser->m_sIPv4, ui16Port, pSpace + 1);
if (iMsgLen > 0)
{
pDcCommand->m_pUser->m_pCmdActive4Search = AddSearch(pDcCommand->m_pUser, pDcCommand->m_pUser->m_pCmdActive4Search, ServerManager::m_pGlobalBuffer, iMsgLen, true);
}
}
else
{
int iMsgLen = snprintf(ServerManager::m_pGlobalBuffer, ServerManager::m_szGlobalBufferSize, "$Search Hub:%s %s", pDcCommand->m_pUser->m_sNick, pSpace + 1);
if (iMsgLen > 0)
{
pDcCommand->m_pUser->m_pCmdPassiveSearch = AddSearch(pDcCommand->m_pUser, pDcCommand->m_pUser->m_pCmdPassiveSearch, ServerManager::m_pGlobalBuffer, iMsgLen, false);
}
}
}
}
else if ((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_IPV4) == User::BIT_IPV4)
{
char * sIP = pDcCommand->m_pUser->m_ui8IPv4Len == 0 ? pDcCommand->m_pUser->m_sIP : pDcCommand->m_pUser->m_sIPv4;
int iMsgLen = snprintf(ServerManager::m_pGlobalBuffer, ServerManager::m_szGlobalBufferSize, "$Search %s:%hu %s", sIP, ui16Port, pSpace + 1);
if (iMsgLen > 0)
{
pDcCommand->m_pUser->m_pCmdActive4Search = AddSearch(pDcCommand->m_pUser, pDcCommand->m_pUser->m_pCmdActive4Search, ServerManager::m_pGlobalBuffer, iMsgLen, true);
}
}
if (ui32IpLen != 0 && pIP[ui32IpLen - 1] == ']')
{
pIP[ui32IpLen - 1] = '\0';
}
else
{
pIP[ui32IpLen] = '\0';
}
if (pIP[0] == '[')
{
pIP++;
}
SendIPFixedMsg(pDcCommand->m_pUser, pIP, pDcCommand->m_pUser->m_sIP);
return;
}
// Restore space after IP:Port
pSpace[0] = ' ';
if (bMulti == true)
{
pDcCommand->m_sCommand[5] = '$';
pDcCommand->m_sCommand += 5;
pDcCommand->m_ui32CommandLen -= 5;
}
if ((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_IPV6) == User::BIT_IPV6)
{
if (pDcCommand->m_sCommand[8] == '[')
{
pDcCommand->m_pUser->m_pCmdActive6Search = AddSearch(pDcCommand->m_pUser, pDcCommand->m_pUser->m_pCmdActive6Search, pDcCommand->m_sCommand, pDcCommand->m_ui32CommandLen, true);
// IPv6 user sent active request.. when he have available IPv4 then create proper IPv4 request too.
if ((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_IPV4) == User::BIT_IPV4)
{
if ((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_IPV4_ACTIVE) == User::BIT_IPV4_ACTIVE)
{
int iMsgLen = snprintf(ServerManager::m_pGlobalBuffer, ServerManager::m_szGlobalBufferSize, "$Search %s:%hu %s", pDcCommand->m_pUser->m_sIPv4, ui16Port, pSpace + 1);
if (iMsgLen > 0)
{
pDcCommand->m_pUser->m_pCmdActive4Search = AddSearch(pDcCommand->m_pUser, pDcCommand->m_pUser->m_pCmdActive4Search, ServerManager::m_pGlobalBuffer, iMsgLen, true);
}
}
else
{
int iMsgLen = snprintf(ServerManager::m_pGlobalBuffer, ServerManager::m_szGlobalBufferSize, "$Search Hub:%s %s", pDcCommand->m_pUser->m_sNick, pSpace + 1);
if (iMsgLen > 0)
{
pDcCommand->m_pUser->m_pCmdPassiveSearch = AddSearch(pDcCommand->m_pUser, pDcCommand->m_pUser->m_pCmdPassiveSearch, ServerManager::m_pGlobalBuffer, iMsgLen, false);
}
}
}
}
else
{
// When IPv6 user sent active search request with IPv4 address (he should't do that) then just send this request...
pDcCommand->m_pUser->m_pCmdActive4Search = AddSearch(pDcCommand->m_pUser, pDcCommand->m_pUser->m_pCmdActive4Search, pDcCommand->m_sCommand, pDcCommand->m_ui32CommandLen, true);
}
}
else
{
pDcCommand->m_pUser->m_pCmdActive4Search = AddSearch(pDcCommand->m_pUser, pDcCommand->m_pUser->m_pCmdActive4Search, pDcCommand->m_sCommand, pDcCommand->m_ui32CommandLen, true);
}
}
}
//---------------------------------------------------------------------------
#ifdef USE_FLYLINKDC_EXT_JSON
//---------------------------------------------------------------------------
// $ExtJSON |
bool DcCommands::ExtJSONDeflood(User * pUser, const char * sData, const uint32_t ui32Len, const bool /* bCheck */)
{
if (CheckExtJSON(pUser, sData, ui32Len) == false)
{
return false;
}
/* TODO
// PPK ... check flood ...
if (bCheck == true && ProfileManager::m_Ptr->IsAllowed(pUser, ProfileManager::NODEFLOODMYINFO) == false) {
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MYINFO_ACTION] != 0) {
if (DeFloodCheckForFlood(pUser, DEFLOOD_MYINFO, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MYINFO_ACTION],
pUser->m_ui16MyINFOs, pUser->m_ui64MyINFOsTick, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MYINFO_MESSAGES],
(uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MYINFO_TIME]) == true) {
return false;
}
}
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MYINFO_ACTION2] != 0) {
if (DeFloodCheckForFlood(pUser, DEFLOOD_MYINFO, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MYINFO_ACTION2],
pUser->m_ui16MyINFOs2, pUser->m_ui64MyINFOsTick2, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MYINFO_MESSAGES2],
(uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MYINFO_TIME2]) == true) {
return false;
}
}
}
if (ui32Len > (uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_MYINFO_LEN]) {
pUser->SendFormat("DcCommands::ExtJSONDeflood", true, "<%s> %s!|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_MYINFO_TOO_LONG]);
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad $ExtJSON from %s (%s) - user closed. (%s)", pUser->m_sNick, pUser->m_sIP, sData);
pUser->Close();
return false;
}
*/
return true;
}
//---------------------------------------------------------------------------
bool DcCommands::CheckExtJSON(User * pUser, const char * sData, const uint32_t ui32Len)
{
if (pUser->m_sNick && pUser->m_ui8NickLen)
{
if (ui32Len > (uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_MYINFO_LEN] * 10)
{
pUser->SendFormat("DcCommands::CheckExtJSON", true, "<%s> %s!|", "Error", "strlen(ExtJSON) > (MaxMyINFOLen * 10)");
//SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_MYINFO_TOO_LONG]
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad $ExtJSON len (%u) from %s (%s) - user closed. (%s)", ui32Len, pUser->m_sNick, pUser->m_sIP, sData);
pUser->Close();
return false;
}
if (ui32Len < pUser->m_ui8NickLen + unsigned(9))
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad $ExtJSON [1] (%s) from %s (%s) - user closed.", sData, pUser->m_sNick, pUser->m_sIP);
pUser->Close();
return false;
}
if ((ui32Len > pUser->m_ui8NickLen + unsigned(9)) && memcmp(sData + 9, pUser->m_sNick, pUser->m_ui8NickLen) != 0)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad $ExtJSON [2] (%s) from %s (%s) - user closed.", sData, pUser->m_sNick, pUser->m_sIP);
pUser->Close();
return false;
}
}
return true;
}
//---------------------------------------------------------------------------
// $ExtJSON |
bool DcCommands::SetExtJSON(User * pUser, const char * sData, const uint32_t ui32Len)
{
if (CheckExtJSON(pUser, sData, ui32Len) == false)
{
return false;
}
if (pUser->ComparExtJSON(sData, ui32Len))
{
return false;
}
pUser->SetExtJSONOriginal(sData, (uint16_t)ui32Len);
if (pUser->m_ui8State >= User::STATE_CLOSING)
{
return false;
}
if (pUser->ProcessRules() == false)
{
pUser->Close();
return false;
}
/*
// PPK ... moved lua here -> another "optimization" ;o)
ScriptManager::m_Ptr->Arrival(pUser, sData, ui32Len, ScriptManager::MYINFO_ARRIVAL);
if (pUser->m_ui8State >= User::STATE_CLOSING) {
return false;
}
*/
pUser->m_ui32BoolBits |= User::BIT_PRCSD_EXT_JSON;
return true;
}
#endif
// $MyINFO $ALL $ $$$$|
bool DcCommands::MyINFODeflood(DcCommand * pDcCommand)
{
if (pDcCommand->m_ui32CommandLen < (22u + pDcCommand->m_pUser->m_ui8NickLen))
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad $MyINFO (%s) from %s (%s) - user closed.", pDcCommand->m_sCommand, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return false;
}
// PPK ... check flood ...
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::NODEFLOODMYINFO) == false)
{
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MYINFO_ACTION] != 0)
{
if (DeFloodCheckForFlood(pDcCommand->m_pUser, DEFLOOD_MYINFO, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MYINFO_ACTION],
pDcCommand->m_pUser->m_ui16MyINFOs, pDcCommand->m_pUser->m_ui64MyINFOsTick, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MYINFO_MESSAGES],
(uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MYINFO_TIME]) == true)
{
return false;
}
}
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MYINFO_ACTION2] != 0)
{
if (DeFloodCheckForFlood(pDcCommand->m_pUser, DEFLOOD_MYINFO, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MYINFO_ACTION2],
pDcCommand->m_pUser->m_ui16MyINFOs2, pDcCommand->m_pUser->m_ui64MyINFOsTick2, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MYINFO_MESSAGES2],
(uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MYINFO_TIME2]) == true)
{
return false;
}
}
}
if (pDcCommand->m_ui32CommandLen > (uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_MYINFO_LEN])
{
pDcCommand->m_pUser->SendFormat("DcCommands::MyINFODeflood", true, "<%s> %s!|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_MYINFO_TOO_LONG]);
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad $MyINFO from %s (%s) - user closed. (%s)", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_sCommand);
pDcCommand->m_pUser->Close();
return false;
}
return true;
}
//---------------------------------------------------------------------------
// $MyINFO $ALL $ $$$$|
bool DcCommands::MyINFO(DcCommand * pDcCommand)
{
// if no change, just return
// else store MyINFO and perform all checks again
if (pDcCommand->m_pUser->m_sMyInfoOriginal != NULL) // PPK ... optimizations
{
if (pDcCommand->m_ui32CommandLen == pDcCommand->m_pUser->m_ui16MyInfoOriginalLen && memcmp(pDcCommand->m_pUser->m_sMyInfoOriginal + 14 + pDcCommand->m_pUser->m_ui8NickLen, pDcCommand->m_sCommand + 14 + pDcCommand->m_pUser->m_ui8NickLen, pDcCommand->m_pUser->m_ui16MyInfoOriginalLen - 14 - pDcCommand->m_pUser->m_ui8NickLen) == 0)
{
return false;
}
}
pDcCommand->m_pUser->SetMyInfoOriginal(pDcCommand->m_sCommand, (uint16_t)pDcCommand->m_ui32CommandLen);
if (pDcCommand->m_pUser->m_ui8State >= User::STATE_CLOSING)
{
return false;
}
if (pDcCommand->m_pUser->ProcessRules() == false)
{
pDcCommand->m_pUser->Close();
return false;
}
// TODO 3 -oPTA -ccheckers: Slots fetching for no tag users
//search command for slots fetch for users without tag
//if(pDcCommand->m_pUser->Tag == NULL)
//{
// pDcCommand->m_pUser->SendText("$Search "+HubAddress->Text+":411 F?F?0?1?.|");
//}
// SEND myinfo to others (including me) only if this is
// a refresh MyINFO event. Else dispatch it in addMe condition
// of service loop
// PPK ... moved lua here -> another "optimization" ;o)
ScriptManager::m_Ptr->Arrival(pDcCommand, ScriptManager::MYINFO_ARRIVAL);
if (pDcCommand->m_pUser->m_ui8State >= User::STATE_CLOSING)
{
return false;
}
return true;
}
//---------------------------------------------------------------------------
// $MyPass
void DcCommands::MyPass(DcCommand * pDcCommand)
{
RegUser * pReg = RegManager::m_Ptr->Find(pDcCommand->m_pUser);
if (pReg != NULL && (pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_WAITING_FOR_PASS) == User::BIT_WAITING_FOR_PASS)
{
pDcCommand->m_pUser->m_ui32BoolBits &= ~User::BIT_WAITING_FOR_PASS;
}
else
{
// We don't send $GetPass!
UdpDebug::m_Ptr->BroadcastFormat("[SYS] $MyPass without request from %s (%s) - user closed.", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
if (pDcCommand->m_ui32CommandLen < 10 || pDcCommand->m_ui32CommandLen > 73)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad $MyPass from %s (%s) - user closed. (%s)", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_sCommand);
pDcCommand->m_pUser->Close();
return;
}
pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - 1] = '\0'; // cutoff pipe
bool bBadPass = false;
if (pReg->m_bPassHash == true)
{
uint8_t ui8Hash[64];
size_t szLen = pDcCommand->m_ui32CommandLen - 9;
if (HashPassword(pDcCommand->m_sCommand + 8, szLen, ui8Hash) == false || memcmp(pReg->m_ui8PassHash, ui8Hash, 64) != 0)
{
bBadPass = true;
}
}
else
{
if (strcmp(pReg->m_sPass, pDcCommand->m_sCommand + 8) != 0)
{
bBadPass = true;
}
}
// if password is wrong, close the connection
if (bBadPass == true)
{
if (SettingManager::m_Ptr->m_bBools[SETBOOL_ADVANCED_PASS_PROTECTION] == true)
{
time(&pReg->m_tLastBadPass);
if (pReg->m_ui8BadPassCount < 255)
pReg->m_ui8BadPassCount++;
}
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_BRUTE_FORCE_PASS_PROTECT_BAN_TYPE] != 0)
{
// brute force password protection
PassBf * PassBfItem = Find(pDcCommand->m_pUser->m_ui128IpHash);
if (PassBfItem == NULL)
{
PassBfItem = new (std::nothrow) PassBf(pDcCommand->m_pUser->m_ui128IpHash);
if (PassBfItem == NULL)
{
AppendDebugLog("%s - [MEM] Cannot allocate new PassBfItem in DcCommands::MyPass\n");
return;
}
if (m_pPasswdBfCheck != NULL)
{
m_pPasswdBfCheck->m_pPrev = PassBfItem;
PassBfItem->m_pNext = m_pPasswdBfCheck;
}
m_pPasswdBfCheck = PassBfItem;
}
else
{
if (PassBfItem->m_iCount == 2)
{
BanItem * pBan = BanManager::m_Ptr->FindFull(pDcCommand->m_pUser->m_ui128IpHash);
if (pBan == NULL || ((pBan->m_ui8Bits & BanManager::FULL) == BanManager::FULL) == false)
{
int iRet = snprintf(ServerManager::m_pGlobalBuffer, ServerManager::m_szGlobalBufferSize, "3x bad password for nick %s", pDcCommand->m_pUser->m_sNick);
if (iRet <= 0)
{
ServerManager::m_pGlobalBuffer[0] = '\0';
}
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_BRUTE_FORCE_PASS_PROTECT_BAN_TYPE] == 1)
{
BanManager::m_Ptr->BanIp(pDcCommand->m_pUser, NULL, ServerManager::m_pGlobalBuffer, NULL, true);
}
else
{
BanManager::m_Ptr->TempBanIp(pDcCommand->m_pUser, NULL, ServerManager::m_pGlobalBuffer, NULL, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_BRUTE_FORCE_PASS_PROTECT_TEMP_BAN_TIME] * 60, 0, true);
}
Remove(PassBfItem);
pDcCommand->m_pUser->SendFormat("DcCommands::MyPass1", false, "<%s> %s.|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_YOUR_IP_BANNED_BRUTE_FORCE_ATTACK]);
}
else
{
pDcCommand->m_pUser->SendFormat("DcCommands::MyPass2", false, "<%s> %s!|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_YOUR_IS_BANNED]);
}
if (SettingManager::m_Ptr->m_bBools[SETBOOL_REPORT_3X_BAD_PASS] == true)
{
GlobalDataQueue::m_Ptr->StatusMessageFormat("DcCommands::MyPass", "<%s> *** %s %s %s %s|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_IP], pDcCommand->m_pUser->m_sIP,
LanguageManager::m_Ptr->m_sTexts[LAN_BANNED_BECAUSE_3X_BAD_PASS_FOR_NICK], pDcCommand->m_pUser->m_sNick);
}
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad 3x password from %s (%s) - user banned. (%s)", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_sCommand);
pDcCommand->m_pUser->Close();
return;
}
else
{
PassBfItem->m_iCount++;
}
}
}
pDcCommand->m_pUser->SendFormat("DcCommands::MyPass3", false, "$BadPass|<%s> %s!|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_INCORRECT_PASSWORD]);
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad password from %s (%s) - user closed. (%s)", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_sCommand);
pDcCommand->m_pUser->Close();
return;
}
else
{
pDcCommand->m_pUser->m_i32Profile = (int32_t)pReg->m_ui16Profile;
pReg->m_ui8BadPassCount = 0;
PassBf * PassBfItem = Find(pDcCommand->m_pUser->m_ui128IpHash);
if (PassBfItem != NULL)
{
Remove(PassBfItem);
}
pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - 1] = '|'; // add back pipe
// PPK ... Lua DataArrival only if pass is ok
ScriptManager::m_Ptr->Arrival(pDcCommand, ScriptManager::PASSWORD_ARRIVAL);
if (pDcCommand->m_pUser->m_ui8State >= User::STATE_CLOSING)
{
return;
}
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::HASKEYICON) == true)
{
pDcCommand->m_pUser->m_ui32BoolBits |= User::BIT_OPERATOR;
}
else
{
pDcCommand->m_pUser->m_ui32BoolBits &= ~User::BIT_OPERATOR;
}
// PPK ... addition for registered users, kill your own ghost >:-]
if (((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_HASHED) == User::BIT_HASHED) == false)
{
User *OtherUser = HashManager::m_Ptr->FindUser(pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_ui8NickLen);
if (OtherUser != NULL)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Ghost %s (%s) closed.", OtherUser->m_sNick, OtherUser->m_sIP);
if (((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_QUICKLIST) == User::SUPPORTBIT_QUICKLIST) == false)
{
OtherUser->Close();
}
else
{
OtherUser->Close(true);
}
}
if (HashManager::m_Ptr->Add(pDcCommand->m_pUser) == false)
{
return;
}
pDcCommand->m_pUser->m_ui32BoolBits |= User::BIT_HASHED;
}
if (((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_QUICKLIST) == User::SUPPORTBIT_QUICKLIST) == false)
{
// welcome the new user
// PPK ... fixed bad DC protocol implementation, $LogedIn is only for OPs !!!
// registered DC1 users have enabled OP menu :)))))))))
if (((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_OPERATOR) == User::BIT_OPERATOR) == true)
{
pDcCommand->m_pUser->SendFormat("DcCommands::MyPass4", true, "$Hello %s|$LogedIn %s|", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sNick);
}
else
{
pDcCommand->m_pUser->SendFormat("DcCommands::MyPass5", true, "$Hello %s|", pDcCommand->m_pUser->m_sNick);
}
return;
}
else
{
if (((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_PINGER) == User::BIT_PINGER) == false)
{
pDcCommand->m_pUser->AddMeOrIPv4Check();
}
}
}
}
//---------------------------------------------------------------------------
// $OpForceMove $Who:<nickname>$Where:<iptoredirect>$Msg:<a message>
void DcCommands::OpForceMove(DcCommand * pDcCommand)
{
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::REDIRECT) == false)
{
pDcCommand->m_pUser->SendFormat("DcCommands::OpForceMove1", true, "<%s> %s!|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_YOU_ARE_NOT_ALWD_TO_USE_THIS_CMD]);
return;
}
if (pDcCommand->m_ui32CommandLen < 31)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad $OpForceMove (%s) from %s (%s) - user closed.", pDcCommand->m_sCommand, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
if (ScriptManager::m_Ptr->Arrival(pDcCommand, ScriptManager::OPFORCEMOVE_ARRIVAL) == true ||
pDcCommand->m_pUser->m_ui8State >= User::STATE_CLOSING)
{
return;
}
pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - 1] = '\0'; // cutoff pipe
char *sCmdParts[] = { NULL, NULL, NULL };
uint16_t iCmdPartsLen[] = { 0, 0, 0 };
uint8_t cPart = 0;
sCmdParts[cPart] = pDcCommand->m_sCommand + 18; // nick start
for (uint32_t ui32i = 18; ui32i < pDcCommand->m_ui32CommandLen; ui32i++)
{
if (pDcCommand->m_sCommand[ui32i] == '$')
{
pDcCommand->m_sCommand[ui32i] = '\0';
iCmdPartsLen[cPart] = (uint16_t)((pDcCommand->m_sCommand + ui32i) - sCmdParts[cPart]);
// are we on last $ ???
if (cPart == 1)
{
sCmdParts[2] = pDcCommand->m_sCommand + ui32i + 1;
iCmdPartsLen[2] = (uint16_t)(pDcCommand->m_ui32CommandLen - ui32i - 1);
break;
}
cPart++;
sCmdParts[cPart] = pDcCommand->m_sCommand + ui32i + 1;
}
}
if (iCmdPartsLen[0] == 0 || iCmdPartsLen[1] < 7 || iCmdPartsLen[2] < 5 || iCmdPartsLen[1] > 4096 || iCmdPartsLen[2] > 16384)
{
return;
}
User *OtherUser = HashManager::m_Ptr->FindUser(sCmdParts[0], iCmdPartsLen[0]);
if(OtherUser)
{
// Self redirect
if(OtherUser == pDcCommand->m_pUser)
{
pDcCommand->m_pUser->SendFormat("DcCommands::OpForceMove2", true, "<%s> %s!|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_YOU_CANT_REDIRECT_YOURSELF]);
return;
}
if(OtherUser->m_i32Profile != -1 && pDcCommand->m_pUser->m_i32Profile > OtherUser->m_i32Profile)
{
pDcCommand->m_pUser->SendFormat("DcCommands::OpForceMove3", true, "<%s> %s %s|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_YOU_ARE_NOT_ALLOWED_TO_REDIRECT], OtherUser->m_sNick);
return;
}
OtherUser->SendFormat("DcCommands::OpForceMove4", false, "<%s> %s %s %s %s. %s: %s|$ForceMove %s|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_YOU_ARE_REDIRECTED_TO], sCmdParts[1]+6,
LanguageManager::m_Ptr->m_sTexts[LAN_BY_LWR], pDcCommand->m_pUser->m_sNick, LanguageManager::m_Ptr->m_sTexts[LAN_MESSAGE], sCmdParts[2] + 4, sCmdParts[1] + 6);
// PPK ... close user !!!
UdpDebug::m_Ptr->BroadcastFormat("[SYS] User %s (%s) redirected by %s", OtherUser->m_sNick, OtherUser->m_sIP, pDcCommand->m_pUser->m_sNick);
OtherUser->Close();
if (SettingManager::m_Ptr->m_bBools[SETBOOL_SEND_STATUS_MESSAGES] == true)
{
GlobalDataQueue::m_Ptr->StatusMessageFormat("DcCommands::OpForceMove", "<%s> *** %s %s %s %s %s. %s: %s|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], OtherUser->m_sNick, LanguageManager::m_Ptr->m_sTexts[LAN_IS_REDIRECTED_TO], sCmdParts[1] + 6,
LanguageManager::m_Ptr->m_sTexts[LAN_BY_LWR], pDcCommand->m_pUser->m_sNick, LanguageManager::m_Ptr->m_sTexts[LAN_MESSAGE], sCmdParts[2] + 4);
}
if (SettingManager::m_Ptr->m_bBools[SETBOOL_SEND_STATUS_MESSAGES] == false || ((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_OPERATOR) == User::BIT_OPERATOR) == false)
{
pDcCommand->m_pUser->SendFormat("DcCommands::OpForceMove4", true, "<%s> *** %s %s %s. %s: %s|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], OtherUser->m_sNick, LanguageManager::m_Ptr->m_sTexts[LAN_IS_REDIRECTED_TO], sCmdParts[1] + 6, LanguageManager::m_Ptr->m_sTexts[LAN_MESSAGE], sCmdParts[2] + 4);
}
}
}
//---------------------------------------------------------------------------
// $RevConnectToMe <ownnick> <nickname>
void DcCommands::RevConnectToMe(DcCommand * pDcCommand)
{
if (pDcCommand->m_ui32CommandLen < 19)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad $RevConnectToMe (%s) from %s (%s) - user closed.", pDcCommand->m_sCommand, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
// PPK ... optimizations
if ((pDcCommand->m_sCommand[16 + pDcCommand->m_pUser->m_ui8NickLen] != ' ') || (memcmp(pDcCommand->m_sCommand + 16, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_ui8NickLen) != 0))
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Nick spoofing in RCTM from %s (%s) - user closed. (%s)", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_sCommand);
pDcCommand->m_pUser->Close();
return;
}
// PPK ... check flood ...
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::NODEFLOODRCTM) == false)
{
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_RCTM_ACTION] != 0)
{
if (DeFloodCheckForFlood(pDcCommand->m_pUser, DEFLOOD_RCTM, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_RCTM_ACTION],
pDcCommand->m_pUser->m_ui16RCTMs, pDcCommand->m_pUser->m_ui64RCTMsTick, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_RCTM_MESSAGES],
(uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_RCTM_TIME]) == true)
{
return;
}
}
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_RCTM_ACTION2] != 0)
{
if (DeFloodCheckForFlood(pDcCommand->m_pUser, DEFLOOD_RCTM, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_RCTM_ACTION2],
pDcCommand->m_pUser->m_ui16RCTMs2, pDcCommand->m_pUser->m_ui64RCTMsTick2, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_RCTM_MESSAGES2],
(uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_RCTM_TIME2]) == true)
{
return;
}
}
}
if (pDcCommand->m_ui32CommandLen > (uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_RCTM_LEN])
{
pDcCommand->m_pUser->SendFormat("DcCommands::RevConnectToMe", true, "<%s> %s!|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_RCTM_TOO_LONG]);
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Long $RevConnectToMe from %s (%s) - user closed. (%s)", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_sCommand);
pDcCommand->m_pUser->Close();
return;
}
// PPK ... $RCTM means user is pasive ?!? Probably yes, let set it not active and use on another places ;)
if (pDcCommand->m_pUser->m_sTag == NULL)
{
pDcCommand->m_pUser->m_ui32BoolBits &= ~User::BIT_IPV4_ACTIVE;
}
if (ScriptManager::m_Ptr->Arrival(pDcCommand, ScriptManager::REVCONNECTTOME_ARRIVAL) == true ||
pDcCommand->m_pUser->m_ui8State >= User::STATE_CLOSING)
{
return;
}
pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - 1] = '\0'; // cutoff pipe
User *OtherUser = HashManager::m_Ptr->FindUser(pDcCommand->m_sCommand + 17 + pDcCommand->m_pUser->m_ui8NickLen, pDcCommand->m_ui32CommandLen - (18 + pDcCommand->m_pUser->m_ui8NickLen));
// PPK ... no connection to yourself !!!
if (OtherUser != NULL && OtherUser != pDcCommand->m_pUser && OtherUser->m_ui8State == User::STATE_ADDED)
{
pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - 1] = '|'; // add back pipe
pDcCommand->m_pUser->AddPrcsdCmd(PrcsdUsrCmd::CTM_MCTM_RCTM_SR_TO, pDcCommand->m_sCommand, pDcCommand->m_ui32CommandLen, OtherUser);
}
}
//---------------------------------------------------------------------------
// $SR <nickname> - Search Respond for passive users
void DcCommands::SR(DcCommand * pDcCommand)
{
if (pDcCommand->m_ui32CommandLen < 6u + pDcCommand->m_pUser->m_ui8NickLen)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad $SR (%s) from %s (%s) - user closed.", pDcCommand->m_sCommand, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
// PPK ... check flood ...
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::NODEFLOODSR) == false)
{
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SR_ACTION] != 0)
{
if (DeFloodCheckForFlood(pDcCommand->m_pUser, DEFLOOD_SR, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SR_ACTION],
pDcCommand->m_pUser->m_ui16SRs, pDcCommand->m_pUser->m_ui64SRsTick, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SR_MESSAGES],
(uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SR_TIME]) == true)
{
return;
}
}
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SR_ACTION2] != 0)
{
if (DeFloodCheckForFlood(pDcCommand->m_pUser, DEFLOOD_SR, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SR_ACTION2],
pDcCommand->m_pUser->m_ui16SRs2, pDcCommand->m_pUser->m_ui64SRsTick2, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SR_MESSAGES2],
(uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SR_TIME2]) == true)
{
return;
}
}
}
if (pDcCommand->m_ui32CommandLen > (uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_SR_LEN])
{
pDcCommand->m_pUser->SendFormat("DcCommands::SR", true, "<%s> %s!|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_SR_TOO_LONG]);
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Long $SR from %s (%s) - user closed. (%s)", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_sCommand);
pDcCommand->m_pUser->Close();
return;
}
// check $SR spoofing (thanx Fusbar)
// PPK... added checking for empty space after nick
if (pDcCommand->m_sCommand[4 + pDcCommand->m_pUser->m_ui8NickLen] != ' ' || memcmp(pDcCommand->m_sCommand + 4, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_ui8NickLen) != 0)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Nick spoofing in SR from %s (%s) - user closed. (%s)", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_sCommand);
pDcCommand->m_pUser->Close();
return;
}
// past SR to script only if it's not a data for SlotFetcher
if (ScriptManager::m_Ptr->Arrival(pDcCommand, ScriptManager::SR_ARRIVAL) == true ||
pDcCommand->m_pUser->m_ui8State >= User::STATE_CLOSING)
{
return;
}
pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - 1] = '\0'; // cutoff pipe
char * pToNick = strrchr(pDcCommand->m_sCommand, '\5');
if (pToNick == NULL) return;
User *OtherUser = HashManager::m_Ptr->FindUser(pToNick + 1, pDcCommand->m_ui32CommandLen - 2 - (pToNick - pDcCommand->m_sCommand));
// PPK ... no $SR to yourself !!!
if (OtherUser != NULL && OtherUser != pDcCommand->m_pUser && OtherUser->m_ui8State == User::STATE_ADDED)
{
// PPK ... search replies limiting
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_PASIVE_SR] != 0)
{
if (OtherUser->m_ui32SR >= (uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_PASIVE_SR])
return;
OtherUser->m_ui32SR++;
}
// cutoff the last part // PPK ... and do it fast ;)
pToNick[0] = '|';
pToNick[1] = '\0';
pDcCommand->m_pUser->AddPrcsdCmd(PrcsdUsrCmd::CTM_MCTM_RCTM_SR_TO, pDcCommand->m_sCommand, pDcCommand->m_ui32CommandLen - OtherUser->m_ui8NickLen - 1, OtherUser);
}
}
//---------------------------------------------------------------------------
#ifdef FLYLINKDC_USE_UDP_THREAD
// $SR <nickname> - Search Respond for active users from UDP
void DcCommands::SRFromUDP(DcCommand * pDcCommand)
{
if (ScriptManager::m_Ptr->Arrival(pDcCommand, ScriptManager::UDP_SR_ARRIVAL) == true ||
pDcCommand->m_pUser->m_ui8State >= User::STATE_CLOSING)
{
return;
}
}
#endif
//---------------------------------------------------------------------------
// $Supports item item item... PPK $Supports UserCommand NoGetINFO NoHello UserIP2 QuickList|
void DcCommands::Supports(DcCommand * pDcCommand)
{
if (((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_HAVE_SUPPORTS) == User::BIT_HAVE_SUPPORTS) == true)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] $Supports flood from %s (%s) - user closed.", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
pDcCommand->m_pUser->m_ui32BoolBits |= User::BIT_HAVE_SUPPORTS;
if (pDcCommand->m_ui32CommandLen < 13)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad $Supports (%s) from %s (%s) - user closed.", pDcCommand->m_sCommand, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
if (pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - 2] == ' ')
{
if (SettingManager::m_Ptr->m_bBools[SETBOOL_NO_QUACK_SUPPORTS] == false)
{
pDcCommand->m_pUser->m_ui32BoolBits |= User::BIT_QUACK_SUPPORTS;
}
else
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Quack $Supports from %s (%s) - user closed. (%s)", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_sCommand);
pDcCommand->m_pUser->SendFormat("DcCommands::Supports1", false, "<%s> %s.|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_QUACK_SUPPORTS]);
pDcCommand->m_pUser->Close();
return;
}
}
ScriptManager::m_Ptr->Arrival(pDcCommand, ScriptManager::SUPPORTS_ARRIVAL);
if (pDcCommand->m_pUser->m_ui8State >= User::STATE_CLOSING)
{
return;
}
char * sSupport = pDcCommand->m_sCommand + 10;
size_t szDataLen;
for (uint32_t ui32i = 10; ui32i < pDcCommand->m_ui32CommandLen - 1; ui32i++)
{
if (pDcCommand->m_sCommand[ui32i] == ' ')
{
pDcCommand->m_sCommand[ui32i] = '\0';
}
else if (ui32i != pDcCommand->m_ui32CommandLen - 2)
{
continue;
}
else
{
ui32i++;
}
szDataLen = (pDcCommand->m_sCommand + ui32i) - sSupport;
switch (sSupport[0])
{
case 'N':
if (sSupport[1] == 'o')
{
if (((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_NOHELLO) == User::SUPPORTBIT_NOHELLO) == false && szDataLen == 7 && memcmp(sSupport + 2, "Hello", 5) == 0)
{
pDcCommand->m_pUser->m_ui32SupportBits |= User::SUPPORTBIT_NOHELLO;
}
else if (((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_NOGETINFO) == User::SUPPORTBIT_NOGETINFO) == false && szDataLen == 9 && memcmp(sSupport + 2, "GetINFO", 7) == 0)
{
pDcCommand->m_pUser->m_ui32SupportBits |= User::SUPPORTBIT_NOGETINFO;
}
}
break;
case 'Q':
{
if (((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_QUICKLIST) == User::SUPPORTBIT_QUICKLIST) == false && szDataLen == 9 && *((uint64_t *)(sSupport + 1)) == *((uint64_t *)"uickList"))
{
pDcCommand->m_pUser->m_ui32SupportBits |= User::SUPPORTBIT_QUICKLIST;
// PPK ... in fact NoHello is only not fully implemented Quicklist (without diferent login sequency)
// That's why i overide NoHello here and use bQuicklist only for login, on other places is same as NoHello ;)
pDcCommand->m_pUser->m_ui32SupportBits |= User::SUPPORTBIT_NOHELLO;
}
break;
}
case 'H':
{
if (((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_HUBURL) == User::SUPPORTBIT_HUBURL) == false && szDataLen == 6 && memcmp(sSupport + 1, "ubURL", 5) == 0)
{
pDcCommand->m_pUser->m_ui32SupportBits |= User::SUPPORTBIT_HUBURL;
}
break; // fix PVS Studio
}
case 'U':
{
if (((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_USERCOMMAND) == User::SUPPORTBIT_USERCOMMAND) == false && szDataLen == 11 && memcmp(sSupport + 1, "serCommand", 10) == 0)
{
pDcCommand->m_pUser->m_ui32SupportBits |= User::SUPPORTBIT_USERCOMMAND;
}
else if (((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_USERIP2) == User::SUPPORTBIT_USERIP2) == false && szDataLen == 7 && memcmp(sSupport + 1, "serIP2", 6) == 0)
{
pDcCommand->m_pUser->m_ui32SupportBits |= User::SUPPORTBIT_USERIP2;
}
break;
}
case 'B':
{
if (((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_PINGER) == User::BIT_PINGER) == false && szDataLen == 7 && memcmp(sSupport + 1, "otINFO", 6) == 0)
{
if (SettingManager::m_Ptr->m_bBools[SETBOOL_DONT_ALLOW_PINGERS] == true)
{
pDcCommand->m_pUser->SendFormat("DcCommands::Supports2", false, "<%s> %s.|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_SORRY_THIS_HUB_NOT_ALLOW_PINGERS]);
pDcCommand->m_pUser->Close();
return;
}
else
{
pDcCommand->m_pUser->m_ui32BoolBits |= User::BIT_PINGER;
pDcCommand->m_pUser->SendFormat("DcCommands::Supports4", true, "%s%" PRIu64 " %s, %" PRIu64 " %s, %" PRIu64 " %s / %s: %u)|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_NAME_WLCM], ServerManager::m_ui64Days, LanguageManager::m_Ptr->m_sTexts[LAN_DAYS_LWR],
ServerManager::m_ui64Hours, LanguageManager::m_Ptr->m_sTexts[LAN_HOURS_LWR], ServerManager::m_ui64Mins, LanguageManager::m_Ptr->m_sTexts[LAN_MINUTES_LWR], LanguageManager::m_Ptr->m_sTexts[LAN_USERS], ServerManager::m_ui32Logged);
}
}
break;
}
case 'Z':
{
if (((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_ZPIPE) == User::SUPPORTBIT_ZPIPE) == false)
{
if (szDataLen == 6 && memcmp(sSupport + 1, "Pipe0", 5) == 0)
{
pDcCommand->m_pUser->m_ui32SupportBits |= User::SUPPORTBIT_ZPIPE0;
pDcCommand->m_pUser->m_ui32SupportBits |= User::SUPPORTBIT_ZPIPE;
m_ui32StatZPipe++;
}
else if (szDataLen == 5 && *((uint32_t *)(sSupport + 1)) == *((uint32_t *)"Pipe"))
{
pDcCommand->m_pUser->m_ui32SupportBits |= User::SUPPORTBIT_ZPIPE;
m_ui32StatZPipe++;
}
}
break;
}
case 'I':
{
if (szDataLen == 4)
{
if (((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_IP64) == User::SUPPORTBIT_IP64) == false && *((uint32_t *)sSupport) == *((uint32_t *)"IP64"))
{
pDcCommand->m_pUser->m_ui32SupportBits |= User::SUPPORTBIT_IP64;
}
else if (((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_IPV4) == User::SUPPORTBIT_IPV4) == false && *((uint32_t *)sSupport) == *((uint32_t *)"IPv4"))
{
pDcCommand->m_pUser->m_ui32SupportBits |= User::SUPPORTBIT_IPV4;
}
}
break;
}
case 'T':
{
if (szDataLen == 4)
{
if (((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_TLS2) == User::SUPPORTBIT_TLS2) == false && *((uint32_t *)sSupport) == *((uint32_t *)"TLS2"))
{
pDcCommand->m_pUser->m_ui32SupportBits |= User::SUPPORTBIT_TLS2;
}
}
break;
}
#ifdef USE_FLYLINKDC_EXT_JSON
case 'E':
{
if (szDataLen == 8)
{
if (pDcCommand->m_pUser->isSupportExtJSON() == false && memcmp(sSupport + 1, "xtJSON2", 7) == 0)
{
pDcCommand->m_pUser->m_is_json_user = true; // |= User::SUPPORTBIT_EXTJSON2;
}
}
break;
}
#endif
case '\0':
{
// PPK ... corrupted $Supports ???
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad $Supports from %s (%s) - user closed.", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
default:
// PPK ... unknown supports
break;
}
sSupport = pDcCommand->m_sCommand + ui32i + 1;
}
pDcCommand->m_pUser->m_ui8State = User::STATE_VALIDATE;
pDcCommand->m_pUser->AddPrcsdCmd(PrcsdUsrCmd::SUPPORTS, NULL, 0, NULL);
}
//---------------------------------------------------------------------------
// $To: nickname From: ownnickname $<ownnickname> <message>
void DcCommands::To(DcCommand * pDcCommand)
{
char * pTemp = strchr(pDcCommand->m_sCommand + 5, ' ');
if (pDcCommand->m_ui32CommandLen < 19 || pTemp == NULL)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad To from %s (%s) - user closed. (%s)", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_sCommand);
pDcCommand->m_pUser->Close();
return;
}
size_t szNickLen = pTemp - (pDcCommand->m_sCommand + 5);
if (szNickLen > 64)
{
pDcCommand->m_pUser->SendFormat("DcCommands::To1", true, "<%s> *** %s!|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_MAX_ALWD_NICK_LEN_64_CHARS]);
return;
}
// is the mesg really from us ?
// PPK ... replaced by better and faster code ;)
int iRet = snprintf(ServerManager::m_pGlobalBuffer, ServerManager::m_szGlobalBufferSize, "From: %s $<%s> ", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sNick);
if (iRet <= 0 || strncmp(pTemp + 1, ServerManager::m_pGlobalBuffer, iRet) != 0)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Nick spoofing in To from %s (%s) - user closed. (%s)", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_sCommand);
pDcCommand->m_pUser->Close();
return;
}
//FloodCheck
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::NODEFLOODPM) == false)
{
// PPK ... pm antiflood
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_PM_ACTION] != 0)
{
pTemp[0] = '\0';
if (DeFloodCheckForFlood(pDcCommand->m_pUser, DEFLOOD_PM, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_PM_ACTION],
pDcCommand->m_pUser->m_ui16PMs, pDcCommand->m_pUser->m_ui64PMsTick, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_PM_MESSAGES],
(uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_PM_TIME], pDcCommand->m_sCommand + 5) == true)
{
return;
}
pTemp[0] = ' ';
}
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_PM_ACTION2] != 0)
{
pTemp[0] = '\0';
if (DeFloodCheckForFlood(pDcCommand->m_pUser, DEFLOOD_PM, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_PM_ACTION2],
pDcCommand->m_pUser->m_ui16PMs2, pDcCommand->m_pUser->m_ui64PMsTick2, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_PM_MESSAGES2],
(uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_PM_TIME2], pDcCommand->m_sCommand + 5) == true)
{
return;
}
pTemp[0] = ' ';
}
// 2nd check for PM flooding
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SAME_PM_ACTION] != 0)
{
bool bNewData = false;
pTemp[0] = '\0';
if (DeFloodCheckForSameFlood(pDcCommand->m_pUser, DEFLOOD_SAME_PM, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SAME_PM_ACTION],
pDcCommand->m_pUser->m_ui16SamePMs, pDcCommand->m_pUser->m_ui64SamePMsTick,
SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SAME_PM_MESSAGES], SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SAME_PM_TIME],
pTemp + (12 + (2 * pDcCommand->m_pUser->m_ui8NickLen)), (pDcCommand->m_ui32CommandLen - (pTemp - pDcCommand->m_sCommand)) - (12 + (2 * pDcCommand->m_pUser->m_ui8NickLen)),
pDcCommand->m_pUser->m_sLastPM, pDcCommand->m_pUser->m_ui16LastPMLen, bNewData, pDcCommand->m_sCommand + 5) == true)
{
return;
}
pTemp[0] = ' ';
if (bNewData == true)
{
pDcCommand->m_pUser->SetLastPM(pTemp + (12 + (2 * pDcCommand->m_pUser->m_ui8NickLen)), (pDcCommand->m_ui32CommandLen - (pTemp - pDcCommand->m_sCommand)) - (12 + (2 * pDcCommand->m_pUser->m_ui8NickLen)));
}
}
}
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::NOCHATLIMITS) == false)
{
// 1st check for length limit for PM message
size_t szMessLen = pDcCommand->m_ui32CommandLen - (2 * pDcCommand->m_pUser->m_ui8NickLen) - (pTemp - pDcCommand->m_sCommand) - 13;
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_PM_LEN] != 0 && szMessLen > (size_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_PM_LEN])
{
// PPK ... hubsec alias
pTemp[0] = '\0';
pDcCommand->m_pUser->SendFormat("DcCommands::To2", true, "$To: %s From: %s $<%s> %s!|", pDcCommand->m_pUser->m_sNick, pDcCommand->m_sCommand + 5, SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_THE_MESSAGE_WAS_TOO_LONG]);
return;
}
// PPK ... check for message lines limit
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_PM_LINES] != 0 || SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SAME_MULTI_PM_ACTION] != 0)
{
if (pDcCommand->m_pUser->m_ui16SamePMs < 2)
{
uint16_t iLines = 1;
for (uint32_t ui32i = 9 + pDcCommand->m_pUser->m_ui8NickLen; ui32i < pDcCommand->m_ui32CommandLen - (pTemp - pDcCommand->m_sCommand) - 1; ui32i++)
{
if (pTemp[ui32i] == '\n')
{
iLines++;
}
}
pDcCommand->m_pUser->m_ui16LastPmLines = iLines;
if (pDcCommand->m_pUser->m_ui16LastPmLines > 1)
{
pDcCommand->m_pUser->m_ui16SameMultiPms++;
}
}
else if (pDcCommand->m_pUser->m_ui16LastPmLines > 1)
{
pDcCommand->m_pUser->m_ui16SameMultiPms++;
}
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::NODEFLOODPM) == false && SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SAME_MULTI_PM_ACTION] != 0)
{
if (pDcCommand->m_pUser->m_ui16SameMultiPms > SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SAME_MULTI_PM_MESSAGES] &&
pDcCommand->m_pUser->m_ui16LastPmLines >= SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SAME_MULTI_PM_LINES])
{
pTemp[0] = '\0';
uint16_t lines = 0;
DeFloodDoAction(pDcCommand->m_pUser, DEFLOOD_SAME_MULTI_PM, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SAME_MULTI_PM_ACTION], lines, pDcCommand->m_sCommand + 5);
return;
}
}
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_PM_LINES] != 0 && pDcCommand->m_pUser->m_ui16LastPmLines > SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_PM_LINES])
{
pTemp[0] = '\0';
pDcCommand->m_pUser->SendFormat("DcCommands::To3", true, "$To: %s From: %s $<%s> %s!|", pDcCommand->m_pUser->m_sNick, pDcCommand->m_sCommand + 5, SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_THE_MESSAGE_WAS_TOO_LONG]);
return;
}
}
}
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::NOPMINTERVAL) == false)
{
pTemp[0] = '\0';
if (DeFloodCheckInterval(pDcCommand->m_pUser, INTERVAL_PM, pDcCommand->m_pUser->m_ui16PMsInt,
pDcCommand->m_pUser->m_ui64PMsIntTick, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_PM_INTERVAL_MESSAGES],
(uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_PM_INTERVAL_TIME], pDcCommand->m_sCommand + 5) == true)
{
return;
}
pTemp[0] = ' ';
}
if (ScriptManager::m_Ptr->Arrival(pDcCommand, ScriptManager::TO_ARRIVAL) == true ||
pDcCommand->m_pUser->m_ui8State >= User::STATE_CLOSING)
{
return;
}
pTemp[0] = '\0';
// ignore the silly debug messages !!!
if (memcmp(pDcCommand->m_sCommand + 5, "Vandel\\Debug", 12) == 0)
{
return;
}
// Everything's ok lets chat
// if this is a PM to OpChat or Hub bot, process the message
if (SettingManager::m_Ptr->m_bBools[SETBOOL_REG_BOT] == true && strcmp(pDcCommand->m_sCommand + 5, SettingManager::m_Ptr->m_sTexts[SETTXT_BOT_NICK]) == 0)
{
pTemp += 9 + pDcCommand->m_pUser->m_ui8NickLen;
// PPK ... check message length, return if no mess found
uint32_t ui32Len1 = (uint32_t)((pDcCommand->m_ui32CommandLen - (pTemp - pDcCommand->m_sCommand)) + 1);
if (ui32Len1 <= pDcCommand->m_pUser->m_ui8NickLen + 4u)
return;
// find chat message data
char *sBuff = pTemp + pDcCommand->m_pUser->m_ui8NickLen + 3;
// non-command chat msg
for (uint8_t ui8i = 0; ui8i < (uint8_t)SettingManager::m_Ptr->m_ui16TextsLens[SETTXT_CHAT_COMMANDS_PREFIXES]; ui8i++)
{
if (sBuff[0] == SettingManager::m_Ptr->m_sTexts[SETTXT_CHAT_COMMANDS_PREFIXES][ui8i])
{
pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - 1] = '\0'; // cutoff pipe
// built-in commands
if (SettingManager::m_Ptr->m_bBools[SETBOOL_ENABLE_TEXT_FILES] == true &&
TextFilesManager::m_Ptr->ProcessTextFilesCmd(pDcCommand->m_pUser, sBuff + 1, true))
{
return;
}
// HubCommands
if (ui32Len1 - pDcCommand->m_pUser->m_ui8NickLen >= 10)
{
if (HubCommands::DoCommand(pDcCommand->m_pUser, sBuff, ui32Len1, true)) return;
}
pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - 1] = '|'; // add back pipe
break;
}
}
// PPK ... if i am here is not textfile request or hub command, try opchat
if (SettingManager::m_Ptr->m_bBools[SETBOOL_REG_OP_CHAT] == true && ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::ALLOWEDOPCHAT) == true &&
SettingManager::m_Ptr->m_bBotsSameNick == true)
{
uint32_t iOpChatLen = SettingManager::m_Ptr->m_ui16TextsLens[SETTXT_OP_CHAT_NICK];
memcpy(pTemp - iOpChatLen - 2, SettingManager::m_Ptr->m_sTexts[SETTXT_OP_CHAT_NICK], iOpChatLen);
pDcCommand->m_pUser->AddPrcsdCmd(PrcsdUsrCmd::TO_OP_CHAT, pTemp - iOpChatLen - 2, pDcCommand->m_ui32CommandLen - ((pTemp - iOpChatLen - 2) - pDcCommand->m_sCommand), NULL);
}
}
else if (SettingManager::m_Ptr->m_bBools[SETBOOL_REG_OP_CHAT] == true &&
ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::ALLOWEDOPCHAT) == true &&
strcmp(pDcCommand->m_sCommand + 5, SettingManager::m_Ptr->m_sTexts[SETTXT_OP_CHAT_NICK]) == 0)
{
pTemp += 9 + pDcCommand->m_pUser->m_ui8NickLen;
uint32_t iOpChatLen = SettingManager::m_Ptr->m_ui16TextsLens[SETTXT_OP_CHAT_NICK];
memcpy(pTemp - iOpChatLen - 2, SettingManager::m_Ptr->m_sTexts[SETTXT_OP_CHAT_NICK], iOpChatLen);
pDcCommand->m_pUser->AddPrcsdCmd(PrcsdUsrCmd::TO_OP_CHAT, pTemp - iOpChatLen - 2, (pDcCommand->m_ui32CommandLen - (pTemp - pDcCommand->m_sCommand)) + iOpChatLen + 2, NULL);
}
else
{
User *OtherUser = HashManager::m_Ptr->FindUser(pDcCommand->m_sCommand + 5, szNickLen);
// PPK ... pm to yourself ?!? NO!
if (OtherUser != NULL && OtherUser != pDcCommand->m_pUser && OtherUser->m_ui8State == User::STATE_ADDED)
{
pTemp[0] = ' ';
pDcCommand->m_pUser->AddPrcsdCmd(PrcsdUsrCmd::CTM_MCTM_RCTM_SR_TO, pDcCommand->m_sCommand, pDcCommand->m_ui32CommandLen, OtherUser, true);
}
}
}
//---------------------------------------------------------------------------
// $ValidateNick
void DcCommands::ValidateNick(DcCommand * pDcCommand)
{
if (((pDcCommand->m_pUser->m_ui32SupportBits & User::SUPPORTBIT_QUICKLIST) == User::SUPPORTBIT_QUICKLIST) == true)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] $ValidateNick with QuickList support from %s (%s) - user closed.", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
if (pDcCommand->m_ui32CommandLen < 16)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Attempt to Validate empty nick (%s) from %s (%s) - user closed.", pDcCommand->m_sCommand, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - 1] = '\0'; // cutoff pipe
if (ValidateUserNick(pDcCommand,pDcCommand->m_pUser, pDcCommand->m_sCommand + 14, pDcCommand->m_ui32CommandLen - 15, true) == false) return;
pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - 1] = '|'; // add back pipe
ScriptManager::m_Ptr->Arrival(pDcCommand, ScriptManager::VALIDATENICK_ARRIVAL);
}
//---------------------------------------------------------------------------
// $Version
void DcCommands::Version(DcCommand * pDcCommand)
{
if (pDcCommand->m_ui32CommandLen < 11)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad $Version (%s) from %s (%s) - user closed.", pDcCommand->m_sCommand, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
pDcCommand->m_pUser->m_ui8State = User::STATE_GETNICKLIST_OR_MYINFO;
ScriptManager::m_Ptr->Arrival(pDcCommand, ScriptManager::VERSION_ARRIVAL);
if (pDcCommand->m_pUser->m_ui8State >= User::STATE_CLOSING)
{
return;
}
pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - 1] = '\0'; // cutoff pipe
pDcCommand->m_pUser->SetVersion(pDcCommand->m_sCommand + 9);
}
//---------------------------------------------------------------------------
// Chat message
bool DcCommands::ChatDeflood(DcCommand * pDcCommand)
{
#ifdef _BUILD_GUI
if (::SendMessage(MainWindowPageUsersChat::m_Ptr->m_hWndPageItems[MainWindowPageUsersChat::BTN_SHOW_CHAT], BM_GETCHECK, 0, 0) == BST_CHECKED)
{
pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - 1] = '\0';
RichEditAppendText(MainWindowPageUsersChat::m_Ptr->m_hWndPageItems[MainWindowPageUsersChat::REDT_CHAT], pDcCommand->m_sCommand);
pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - 1] = '|';
}
#endif
// if the user is sending chat as other user, kick him
if (pDcCommand->m_sCommand[1 + pDcCommand->m_pUser->m_ui8NickLen] != '>' || pDcCommand->m_sCommand[2 + pDcCommand->m_pUser->m_ui8NickLen] != ' ' || memcmp(pDcCommand->m_pUser->m_sNick, pDcCommand->m_sCommand + 1, pDcCommand->m_pUser->m_ui8NickLen) != 0)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Nick spoofing in chat from %s (%s) - user closed. (%s)", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_sCommand);
pDcCommand->m_pUser->Close();
return false;
}
// PPK ... check flood...
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::NODEFLOODMAINCHAT) == false)
{
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAIN_CHAT_ACTION] != 0)
{
if (DeFloodCheckForFlood(pDcCommand->m_pUser, DEFLOOD_CHAT, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAIN_CHAT_ACTION],
pDcCommand->m_pUser->m_ui16ChatMsgs, pDcCommand->m_pUser->m_ui64ChatMsgsTick, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAIN_CHAT_MESSAGES],
(uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAIN_CHAT_TIME]) == true)
{
return false;
}
}
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAIN_CHAT_ACTION2] != 0)
{
if (DeFloodCheckForFlood(pDcCommand->m_pUser, DEFLOOD_CHAT, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAIN_CHAT_ACTION2],
pDcCommand->m_pUser->m_ui16ChatMsgs2, pDcCommand->m_pUser->m_ui64ChatMsgsTick2, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAIN_CHAT_MESSAGES2],
(uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAIN_CHAT_TIME2]) == true)
{
return false;
}
}
// 2nd check for chatmessage flood
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SAME_MAIN_CHAT_ACTION] != 0)
{
bool bNewData = false;
if (DeFloodCheckForSameFlood(pDcCommand->m_pUser, DEFLOOD_SAME_CHAT, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SAME_MAIN_CHAT_ACTION],
pDcCommand->m_pUser->m_ui16SameChatMsgs, pDcCommand->m_pUser->m_ui64SameChatsTick,
SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SAME_MAIN_CHAT_MESSAGES], SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SAME_MAIN_CHAT_TIME],
pDcCommand->m_sCommand + pDcCommand->m_pUser->m_ui8NickLen + 3, pDcCommand->m_ui32CommandLen - (pDcCommand->m_pUser->m_ui8NickLen + 3), pDcCommand->m_pUser->m_sLastChat, pDcCommand->m_pUser->m_ui16LastChatLen, bNewData) == true)
{
return false;
}
if (bNewData == true)
{
pDcCommand->m_pUser->SetLastChat(pDcCommand->m_sCommand + pDcCommand->m_pUser->m_ui8NickLen + 3, pDcCommand->m_ui32CommandLen - (pDcCommand->m_pUser->m_ui8NickLen + 3));
}
}
}
// PPK ... ignore empty chat ;)
if (pDcCommand->m_ui32CommandLen < pDcCommand->m_pUser->m_ui8NickLen + 5u)
{
return false;
}
return true;
}
//---------------------------------------------------------------------------
// Chat message
void DcCommands::Chat(DcCommand * pDcCommand)
{
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::NOCHATLIMITS) == false)
{
// PPK ... check for message limit length
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_CHAT_LEN] != 0 && (pDcCommand->m_ui32CommandLen - pDcCommand->m_pUser->m_ui8NickLen - 4) > (uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_CHAT_LEN])
{
pDcCommand->m_pUser->SendFormat("DcCommands::Chat1", true, "<%s> %s !|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_THE_MESSAGE_WAS_TOO_LONG]);
return;
}
// PPK ... check for message lines limit
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_CHAT_LINES] != 0 || SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SAME_MULTI_MAIN_CHAT_ACTION] != 0)
{
if (pDcCommand->m_pUser->m_ui16SameChatMsgs < 2)
{
uint16_t iLines = 1;
for (uint32_t ui32i = pDcCommand->m_pUser->m_ui8NickLen + 3; ui32i < pDcCommand->m_ui32CommandLen - 1; ui32i++)
{
if (pDcCommand->m_sCommand[ui32i] == '\n')
{
iLines++;
}
}
pDcCommand->m_pUser->m_ui16LastChatLines = iLines;
if (pDcCommand->m_pUser->m_ui16LastChatLines > 1)
{
pDcCommand->m_pUser->m_ui16SameMultiChats++;
}
}
else if (pDcCommand->m_pUser->m_ui16LastChatLines > 1)
{
pDcCommand->m_pUser->m_ui16SameMultiChats++;
}
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::NODEFLOODMAINCHAT) == false && SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SAME_MULTI_MAIN_CHAT_ACTION] != 0)
{
if (pDcCommand->m_pUser->m_ui16SameMultiChats > SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SAME_MULTI_MAIN_CHAT_MESSAGES] &&
pDcCommand->m_pUser->m_ui16LastChatLines >= SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SAME_MULTI_MAIN_CHAT_LINES])
{
uint16_t lines = 0;
DeFloodDoAction(pDcCommand->m_pUser, DEFLOOD_SAME_MULTI_CHAT, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_SAME_MULTI_MAIN_CHAT_ACTION], lines, NULL);
return;
}
}
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_CHAT_LINES] != 0 && pDcCommand->m_pUser->m_ui16LastChatLines > SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_CHAT_LINES])
{
pDcCommand->m_pUser->SendFormat("DcCommands::Chat2", true, "<%s> %s !|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_THE_MESSAGE_WAS_TOO_LONG]);
return;
}
}
}
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::NOCHATINTERVAL) == false)
{
if (DeFloodCheckInterval(pDcCommand->m_pUser, INTERVAL_CHAT, pDcCommand->m_pUser->m_ui16ChatIntMsgs,
pDcCommand->m_pUser->m_ui64ChatIntMsgsTick, SettingManager::m_Ptr->m_i16Shorts[SETSHORT_CHAT_INTERVAL_MESSAGES],
(uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_CHAT_INTERVAL_TIME]) == true)
{
return;
}
}
if (((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_GAGGED) == User::BIT_GAGGED) == true)
return;
void * pQueueItem1 = GlobalDataQueue::m_Ptr->GetLastQueueItem();
if (ScriptManager::m_Ptr->Arrival(pDcCommand, ScriptManager::CHAT_ARRIVAL) == true ||
pDcCommand->m_pUser->m_ui8State >= User::STATE_CLOSING)
{
return;
}
void * pQueueItem = NULL;
void * pQueueItem2 = GlobalDataQueue::m_Ptr->GetLastQueueItem();
if (pQueueItem1 != pQueueItem2)
{
if (pQueueItem1 == NULL)
{
pQueueItem = GlobalDataQueue::m_Ptr->InsertBlankQueueItem(GlobalDataQueue::m_Ptr->GetFirstQueueItem(), GlobalDataQueue::CMD_CHAT);
}
else
{
pQueueItem = GlobalDataQueue::m_Ptr->InsertBlankQueueItem(pQueueItem1, GlobalDataQueue::CMD_CHAT);
}
if (pQueueItem != NULL)
{
pDcCommand->m_pUser->m_ui32BoolBits |= User::BIT_CHAT_INSERT;
}
}
else if ((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_CHAT_INSERT) == User::BIT_CHAT_INSERT)
{
pQueueItem = GlobalDataQueue::m_Ptr->InsertBlankQueueItem(pQueueItem1, GlobalDataQueue::CMD_CHAT);
}
// PPK ... filtering kick messages
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::KICK) == true)
{
if (pDcCommand->m_ui32CommandLen > pDcCommand->m_pUser->m_ui8NickLen + 21u)
{
char * pTemp = strchr(pDcCommand->m_sCommand + pDcCommand->m_pUser->m_ui8NickLen + 3, '\n');
if (pTemp != NULL)
{
pTemp[0] = '\0';
}
char * pIsKicking = stristr(pDcCommand->m_sCommand + pDcCommand->m_pUser->m_ui8NickLen + 3, "is kicking ");
if (pIsKicking != NULL)
{
char * pBecause = stristr(pIsKicking + 12, " because: ");
if (pBecause != NULL)
{
// PPK ... catch kick message and store for later use in $Kick for tempban reason
pBecause[0] = '\0';
User * KickedUser = HashManager::m_Ptr->FindUser(pIsKicking + 11, pBecause - (pIsKicking + 11));
pBecause[0] = ' ';
if (KickedUser != NULL)
{
// PPK ... valid kick messages for existing user, remove this message from deflood ;)
if (pDcCommand->m_pUser->m_ui16ChatMsgs != 0)
{
pDcCommand->m_pUser->m_ui16ChatMsgs--;
pDcCommand->m_pUser->m_ui16ChatMsgs2--;
}
if (pBecause[10] != '|')
{
pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - 1] = '\0'; // get rid of the pipe
KickedUser->SetBuffer(pBecause + 10, pDcCommand->m_ui32CommandLen - (pBecause - pDcCommand->m_sCommand) - 11);
pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - 1] = '|'; // add back pipe
}
}
if (pTemp != NULL)
{
pTemp[0] = '\n';
}
// PPK ... kick messages filtering
if (SettingManager::m_Ptr->m_bBools[SETBOOL_FILTER_KICK_MESSAGES] == true)
{
if (SettingManager::m_Ptr->m_bBools[SETBOOL_SEND_KICK_MESSAGES_TO_OPS] == true)
{
if (SettingManager::m_Ptr->m_bBools[SETBOOL_SEND_STATUS_MESSAGES_AS_PM] == true)
{
int iRet = snprintf(ServerManager::m_pGlobalBuffer, ServerManager::m_szGlobalBufferSize, "%s $%s", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], pDcCommand->m_sCommand);
if (iRet > 0)
{
GlobalDataQueue::m_Ptr->SingleItemStore(ServerManager::m_pGlobalBuffer, iRet, NULL, 0, GlobalDataQueue::SI_PM2OPS);
}
}
else
{
GlobalDataQueue::m_Ptr->AddQueueItem(pDcCommand->m_sCommand, pDcCommand->m_ui32CommandLen, NULL, 0, GlobalDataQueue::CMD_OPS);
}
}
else
{
pDcCommand->m_pUser->SendCharDelayed(pDcCommand->m_sCommand, pDcCommand->m_ui32CommandLen);
}
return;
}
}
}
if (pTemp != NULL)
{
pTemp[0] = '\n';
}
}
}
pDcCommand->m_pUser->AddPrcsdCmd(PrcsdUsrCmd::CHAT, pDcCommand->m_sCommand, pDcCommand->m_ui32CommandLen, reinterpret_cast<User *>(pQueueItem));
#ifdef FLYLINKDC_USE_DB
#ifdef _WITH_SQLITE
DBSQLite::m_Ptr->IncMessageCount(pDcCommand->m_pUser);
#endif
#endif
}
//---------------------------------------------------------------------------
// $Close nick|
void DcCommands::Close(DcCommand * pDcCommand)
{
if (ProfileManager::m_Ptr->IsAllowed(pDcCommand->m_pUser, ProfileManager::CLOSE) == false)
{
pDcCommand->m_pUser->SendFormat("DcCommands::Close1", true, "<%s> %s!|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_YOU_ARE_NOT_ALWD_TO_USE_THIS_CMD]);
return;
}
if (pDcCommand->m_ui32CommandLen < 9)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad $Close (%s) from %s (%s) - user closed.", pDcCommand->m_sCommand, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
pDcCommand->m_pUser->Close();
return;
}
if (ScriptManager::m_Ptr->Arrival(pDcCommand, ScriptManager::CLOSE_ARRIVAL) == true || pDcCommand->m_pUser->m_ui8State >= User::STATE_CLOSING)
{
return;
}
pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - 1] = '\0'; // cutoff pipe
User *OtherUser = HashManager::m_Ptr->FindUser(pDcCommand->m_sCommand + 7, pDcCommand->m_ui32CommandLen - 8);
if (OtherUser != NULL)
{
// Self-kick
if (OtherUser == pDcCommand->m_pUser)
{
pDcCommand->m_pUser->SendFormat("DcCommands::Close2", true, "<%s> %s!|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_YOU_CANT_CLOSE_YOURSELF]);
return;
}
if (OtherUser->m_i32Profile != -1 && pDcCommand->m_pUser->m_i32Profile > OtherUser->m_i32Profile)
{
pDcCommand->m_pUser->SendFormat("DcCommands::Close3", true, "<%s> %s %s!|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_YOU_ARE_NOT_ALLOWED_TO_CLOSE], OtherUser->m_sNick);
return;
}
// disconnect the user
UdpDebug::m_Ptr->BroadcastFormat("[SYS] User %s (%s) closed by %s", OtherUser->m_sNick, OtherUser->m_sIP, pDcCommand->m_pUser->m_sNick);
OtherUser->Close();
if (SettingManager::m_Ptr->m_bBools[SETBOOL_SEND_STATUS_MESSAGES] == true)
{
GlobalDataQueue::m_Ptr->StatusMessageFormat("DcCommands::Close", "<%s> *** %s %s %s %s %s.|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], OtherUser->m_sNick, LanguageManager::m_Ptr->m_sTexts[LAN_WITH_IP], OtherUser->m_sIP,
LanguageManager::m_Ptr->m_sTexts[LAN_WAS_CLOSED_BY], pDcCommand->m_pUser->m_sNick);
}
if (SettingManager::m_Ptr->m_bBools[SETBOOL_SEND_STATUS_MESSAGES] == false || ((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_OPERATOR) == User::BIT_OPERATOR) == false)
{
pDcCommand->m_pUser->SendFormat("DcCommands::Close4", true, "<%s> *** %s %s %s %s.|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], OtherUser->m_sNick, LanguageManager::m_Ptr->m_sTexts[LAN_WITH_IP], OtherUser->m_sIP, LanguageManager::m_Ptr->m_sTexts[LAN_WAS_CLOSED]);
}
}
}
//---------------------------------------------------------------------------
void DcCommands::Unknown(DcCommand * pDcCommand, const bool bMyNick/* = false*/)
{
m_ui32StatCmdUnknown++;
#ifdef _DBG
Memo(">>> Unimplemented Cmd " + pUser->Nick + " [" + pUser->IP + "]: " + sData);
#endif
// if we got unknown command sooner than full login finished
// PPK ... fixed posibility to send (or flood !!!) hub with unknown command before full login
// Give him chance with script...
// if this is unkncwn command and script dont clarify that it's ok, disconnect the user
if (ScriptManager::m_Ptr->Arrival(pDcCommand, ScriptManager::UNKNOWN_ARRIVAL) == false)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Unknown command from %s (%s) - user closed. (%s)", pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP, pDcCommand->m_sCommand);
if (bMyNick == true)
{
pDcCommand->m_pUser->SendCharDelayed("$Error CTM2HUB|", 15);
}
pDcCommand->m_pUser->Close();
}
}
//---------------------------------------------------------------------------
bool DcCommands::ValidateUserNick(DcCommand * pDcCommand,User * pUser, char * sNick, const size_t szNickLen, const bool ValidateNick)
{
// illegal characters in nick?
for (uint32_t ui32i = 0; ui32i < szNickLen; ui32i++)
{
switch (sNick[ui32i])
{
case ' ':
case '$':
case '|':
{
pUser->SendFormat("DcCommands::ValidateUserNick1", false, "<%s> %s '%c' ! %s.|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_YOUR_NICK_CONTAINS_ILLEGAL_CHARACTER], sNick[ui32i], LanguageManager::m_Ptr->m_sTexts[LAN_PLS_CORRECT_IT_AND_GET_BACK_AGAIN]);
// UdpDebug::m_Ptr->BroadcastFormat("[SYS] Nick with bad chars (%s) from %s (%s) - user closed.", Nick, pUser->m_sNick, pUser->m_sIP);
pUser->Close();
return false;
}
default:
if ((unsigned char)sNick[ui32i] < 32)
{
pUser->SendFormat("DcCommands::ValidateUserNick2", false, "<%s> %s! %s.|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_YOUR_NICK_CONTAINS_ILLEGAL_WHITE_CHARACTER], LanguageManager::m_Ptr->m_sTexts[LAN_PLS_CORRECT_IT_AND_GET_BACK_AGAIN]);
// UdpDebug::m_Ptr->BroadcastFormat("[SYS] Nick with white chars (%s) from %s (%s) - user closed.", Nick, pUser->m_sNick, pUser->m_sIP);
pUser->Close();
return false;
}
continue;
}
}
pUser->SetNick(sNick, (uint8_t)szNickLen);
// check for reserved nicks
if (ReservedNicksManager::m_Ptr->CheckReserved(pUser->m_sNick, pUser->m_ui32NickHash) == true)
{
pUser->SendFormat("DcCommands::ValidateUserNick3", false, "<%s> %s. %s.|$ValidateDenide %s|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_THE_NICK_IS_RESERVED_FOR_SOMEONE_OTHER], LanguageManager::m_Ptr->m_sTexts[LAN_CHANGE_YOUR_NICK_AND_GET_BACK_AGAIN], sNick);
// UdpDebug::m_Ptr->BroadcastFormat("[SYS] Reserved nick (%s) from %s (%s) - user closed.", Nick, pUser->m_sNick, pUser->m_sIP);
pUser->Close();
return false;
}
// PPK ... check if we already have ban for this user
if (pUser->m_LogInOut.m_pBan != NULL && pUser->m_ui32NickHash == pUser->m_LogInOut.m_pBan->m_ui32NickHash)
{
pUser->SendChar(pUser->m_LogInOut.m_pBan->m_sMessage, pUser->m_LogInOut.m_pBan->m_ui32Len);
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Banned user %s (%s) - user closed.", pUser->m_sNick, pUser->m_sIP);
pUser->Close();
return false;
}
time_t tmAccTime;
time(&tmAccTime);
// check for banned nicks
BanItem * pBan = BanManager::m_Ptr->FindNick(pUser);
if (pBan != NULL)
{
int iMsgLen = GenerateBanMessage(pBan, tmAccTime);
if (iMsgLen != 0)
{
pUser->SendChar(ServerManager::m_pGlobalBuffer, iMsgLen);
}
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Banned user %s (%s) - user closed.", pUser->m_sNick, pUser->m_sIP);
pUser->Close();
return false;
}
int32_t i32Profile = -1;
// Nick is ok, check for registered nick
RegUser *Reg = RegManager::m_Ptr->Find(pUser);
if (Reg != NULL)
{
if (SettingManager::m_Ptr->m_bBools[SETBOOL_ADVANCED_PASS_PROTECTION] == true && Reg->m_ui8BadPassCount != 0)
{
uint32_t iMinutes2Wait = (uint32_t)pow(2.0, (double)Reg->m_ui8BadPassCount - 1);
if (tmAccTime < (time_t)(Reg->m_tLastBadPass + (60 * iMinutes2Wait)))
{
pUser->SendFormat("DcCommands::ValidateUserNick4", false, "<%s> %s %s %s!|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_LAST_PASS_WAS_WRONG_YOU_NEED_WAIT], formatSecTime((Reg->m_tLastBadPass + (60 * iMinutes2Wait)) - tmAccTime),
LanguageManager::m_Ptr->m_sTexts[LAN_BEFORE_YOU_TRY_AGAIN]);
UdpDebug::m_Ptr->BroadcastFormat("[SYS] User %s (%s) not allowed to send password (%" PRIu64 ") - user closed.", pUser->m_sNick, pUser->m_sIP, (uint64_t)((Reg->m_tLastBadPass + (60 * iMinutes2Wait)) - tmAccTime));
pUser->Close();
return false;
}
}
i32Profile = (int32_t)Reg->m_ui16Profile;
}
// PPK ... moved IP ban check here, we need to allow registered users on shared IP to log in if not have banned nick, but only IP.
if (ProfileManager::m_Ptr->IsProfileAllowed(i32Profile, ProfileManager::ENTERIFIPBAN) == false)
{
// PPK ... check if we already have ban for this user
if (pUser->m_LogInOut.m_pBan != NULL)
{
pUser->SendChar(pUser->m_LogInOut.m_pBan->m_sMessage, pUser->m_LogInOut.m_pBan->m_ui32Len);
// UdpDebug::m_Ptr->BroadcastFormat("[SYS] uBanned user %s (%s) - user closed.", pUser->m_sNick, pUser->m_sIP);
pUser->Close();
return false;
}
}
// PPK ... delete user ban if we have it
if (pUser->m_LogInOut.m_pBan != NULL)
{
delete pUser->m_LogInOut.m_pBan;
pUser->m_LogInOut.m_pBan = NULL;
}
// first check for user limit ! PPK ... allow hublist pinger to check hub any time ;)
if (ProfileManager::m_Ptr->IsProfileAllowed(i32Profile, ProfileManager::ENTERFULLHUB) == false && ((pUser->m_ui32BoolBits & User::BIT_PINGER) == User::BIT_PINGER) == false)
{
// user is NOT allowed enter full hub, check for maxClients
if (ServerManager::m_ui32Joins - ServerManager::m_ui32Parts > (uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_USERS])
{
pUser->SendFormat("DcCommands::ValidateUserNick5", false, "$HubIsFull|<%s> %s. %u %s.|%s", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_THIS_HUB_IS_FULL], ServerManager::m_ui32Logged, LanguageManager::m_Ptr->m_sTexts[LAN_USERS_ONLINE_LWR],
(SettingManager::m_Ptr->m_bBools[SETBOOL_REDIRECT_WHEN_HUB_FULL] == true && SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_REDIRECT_ADDRESS] != NULL) ? SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_REDIRECT_ADDRESS] : "");
// UdpDebug::m_Ptr->BroadcastFormat("[SYS] Hub full for %s (%s) - user closed.", pUser->m_sNick, pUser->m_sIP);
pUser->Close();
return false;
}
}
// Check for maximum connections from same IP
if (ProfileManager::m_Ptr->IsProfileAllowed(i32Profile, ProfileManager::NOUSRSAMEIP) == false)
{
uint32_t ui32Count = HashManager::m_Ptr->GetUserIpCount(pUser);
if (ui32Count >= (uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_CONN_SAME_IP])
{
pUser->SendFormat("DcCommands::ValidateUserNick6", false, "<%s> %s.|%s", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_SORRY_ALREADY_MAX_IP_CONNS],
(SettingManager::m_Ptr->m_bBools[SETBOOL_REDIRECT_WHEN_HUB_FULL] == true && SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_REDIRECT_ADDRESS] != NULL) ? SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_REDIRECT_ADDRESS] : "");
int iMsgLen = snprintf(ServerManager::m_pGlobalBuffer, ServerManager::m_szGlobalBufferSize, "[SYS] Max connections from same IP (%u) for %s (%s) - user closed. ", ui32Count, pUser->m_sNick, pUser->m_sIP);
if (iMsgLen <= 0)
{
pUser->Close();
return false;
}
//UdpDebug::m_Ptr->Broadcast(ServerManager::m_pGlobalBuffer, iMsgLen);
string tmp(ServerManager::m_pGlobalBuffer, iMsgLen);
User * cur = NULL,
* nxt = HashManager::m_Ptr->FindUser(pUser->m_ui128IpHash);
while (nxt != NULL)
{
cur = nxt;
nxt = cur->m_pHashIpTableNext;
tmp += " " + string(cur->m_sNick, cur->m_ui8NickLen);
}
UdpDebug::m_Ptr->Broadcast(tmp.c_str(), tmp.size());
pUser->Close();
return false;
}
}
// Check for reconnect time
if (ProfileManager::m_Ptr->IsProfileAllowed(i32Profile, ProfileManager::NORECONNTIME) == false && Users::m_Ptr->CheckRecTime(pUser) == true)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Fast reconnect from %s (%s) - user closed.", pUser->m_sNick, pUser->m_sIP);
pUser->Close();
return false;
}
pUser->m_ui8Country = IpP2Country::m_Ptr->Find(pUser->m_ui128IpHash);
// check for nick in userlist. If taken, check for dupe's socket state
// if still active, send $ValidateDenide and close()
User *OtherUser = HashManager::m_Ptr->FindUser(pUser);
if (OtherUser != NULL)
{
if (OtherUser->m_ui8State < User::STATE_CLOSING)
{
// check for socket error, or if user closed connection
int iRet = recv(OtherUser->m_Socket, ServerManager::m_pGlobalBuffer, 16, MSG_PEEK);
//GlobalDataQueue::m_Ptr->PrometheusRecvBytes("dccommand",recvlen);
// if socket error or user closed connection then allow new user to log in
#ifdef _WIN32
if ((iRet == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK) || iRet == 0)
{
#else
if ((iRet == -1 && errno != EAGAIN) || iRet == 0)
{
#endif
OtherUser->m_ui32BoolBits |= User::BIT_ERROR;
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Detected clone of yourself, byebye! Nick %s (%s) - user closed. Please close the second DC++ client! ", OtherUser->m_sNick, OtherUser->m_sIP);
OtherUser->Close();
return false;
}
else
{
if (Reg == NULL)
{
// alex82 ... �������� ValidateDenideArrival
ScriptManager::m_Ptr->Arrival(pDcCommand, ScriptManager::VALIDATE_DENIDE_ARRIVAL);
#ifdef FLYLINKDC_USE_REMOVE_CLONE // ���� ��������. ��������
if (// TODO OtherUser->m_ui64SharedSize == pUser->m_ui64SharedSize &&
strcmp(OtherUser->m_sNick, pUser->m_sNick) == 0 && strcmp(OtherUser->m_sIP, pUser->m_sIP) == 0) //[+] FlylinkDC++
{
OtherUser->SendFormat("DcCommands::ValidateUserNick8", false, "Detected clone of yourself, byebye!Nick %s(%s) - user closed.Please close the second DC++ client!|",
SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC],
sNick);
OtherUser->m_ui32BoolBits |= User::BIT_ERROR;
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Remove clone user nick %s (%s) - user closed.", OtherUser->m_sNick, OtherUser->m_sIP);
OtherUser->Close();
return ValidateUserNickFinally(Reg == NULL, pUser, szNickLen, ValidateNick); // [+] FlylinkDC++
}
else
#endif // FLYLINKDC_USE_REMOVE_CLONE
{
pUser->SendFormat("DcCommands::ValidateUserNick7", false, "$ValidateDenide %s|", sNick);
if (strcmp(OtherUser->m_sIP, pUser->m_sIP) != 0 || strcmp(OtherUser->m_sNick, pUser->m_sNick) != 0)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Nick taken [%s (%s)] %s (%s) - user closed.", OtherUser->m_sNick, OtherUser->m_sIP, pUser->m_sNick, pUser->m_sIP);
}
pUser->Close();
return false;
}
}
else
{
// PPK ... addition for registered users, kill your own ghost >:-]
pUser->m_ui8State = User::STATE_VERSION_OR_MYPASS;
pUser->m_ui32BoolBits |= User::BIT_WAITING_FOR_PASS;
pUser->AddPrcsdCmd(PrcsdUsrCmd::GETPASS, NULL, 0, NULL);
return true;
}
}
}
}
return ValidateUserNickFinally(Reg == NULL, pUser, szNickLen, ValidateNick); // [+] FlylinkDC++
}
// [+] FlylinkDC++
//---------------------------------------------------------------------------
bool DcCommands::ValidateUserNickFinally(bool pIsNotReg, User * pUser, const size_t szNickLen, const bool ValidateNick)
{
if (pIsNotReg)
{
// user is NOT registered
// nick length check
if ((SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MIN_NICK_LEN] != 0 && szNickLen < (uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MIN_NICK_LEN]) ||
(SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_NICK_LEN] != 0 && szNickLen > (uint32_t)SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MAX_NICK_LEN]))
{
pUser->SendChar(SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_NICK_LIMIT_MSG], SettingManager::m_Ptr->m_ui16PreTextsLens[SettingManager::SETPRETXT_NICK_LIMIT_MSG]);
// UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad nick length (%d) from %s (%s) - user closed.", (int)szNickLen, pUser->m_sNick, pUser->m_sIP);
pUser->Close();
return false;
}
if (SettingManager::m_Ptr->m_bBools[SETBOOL_REG_ONLY] == true && ((pUser->m_ui32BoolBits & User::BIT_PINGER) == User::BIT_PINGER) == false)
{
pUser->SendChar(SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_REG_ONLY_MSG], SettingManager::m_Ptr->m_ui16PreTextsLens[SettingManager::SETPRETXT_REG_ONLY_MSG]);
// UdpDebug::m_Ptr->BroadcastFormat("[SYS] Hub for reg only %s (%s) - user closed.", pUser->m_sNick, pUser->m_sIP);
pUser->Close();
return false;
}
else
{
// hub is public, proceed to Hello
if (HashManager::m_Ptr->Add(pUser) == false)
{
return false;
}
pUser->m_ui32BoolBits |= User::BIT_HASHED;
if (ValidateNick == true)
{
pUser->m_ui8State = User::STATE_VERSION_OR_MYPASS; // waiting for $Version
pUser->AddPrcsdCmd(PrcsdUsrCmd::LOGINHELLO, NULL, 0, NULL);
}
return true;
}
}
else
{
// user is registered, wait for password
if (HashManager::m_Ptr->Add(pUser) == false)
{
return false;
}
pUser->m_ui32BoolBits |= User::BIT_HASHED;
pUser->m_ui8State = User::STATE_VERSION_OR_MYPASS;
pUser->m_ui32BoolBits |= User::BIT_WAITING_FOR_PASS;
pUser->AddPrcsdCmd(PrcsdUsrCmd::GETPASS, NULL, 0, NULL);
return true;
}
return false;
}
//---------------------------------------------------------------------------
DcCommands::PassBf * DcCommands::Find(const uint8_t * ui128IpHash)
{
PassBf * cur = NULL,
* next = m_pPasswdBfCheck;
while (next != NULL)
{
cur = next;
next = cur->m_pNext;
if (memcmp(cur->m_ui128IpHash, ui128IpHash, 16) == 0)
{
return cur;
}
}
return NULL;
}
//---------------------------------------------------------------------------
void DcCommands::Remove(PassBf * pPassBfItem)
{
if (pPassBfItem->m_pPrev == NULL)
{
if (pPassBfItem->m_pNext == NULL)
{
m_pPasswdBfCheck = NULL;
}
else
{
pPassBfItem->m_pNext->m_pPrev = NULL;
m_pPasswdBfCheck = pPassBfItem->m_pNext;
}
}
else if (pPassBfItem->m_pNext == NULL)
{
pPassBfItem->m_pPrev->m_pNext = NULL;
}
else
{
pPassBfItem->m_pPrev->m_pNext = pPassBfItem->m_pNext;
pPassBfItem->m_pNext->m_pPrev = pPassBfItem->m_pPrev;
}
delete pPassBfItem;
}
//---------------------------------------------------------------------------
void DcCommands::ProcessCmds(User * pUser)
{
pUser->m_ui32BoolBits &= ~User::BIT_CHAT_INSERT;
PrcsdUsrCmd * cur = NULL,
* next = pUser->m_pCmdStrt;
while (next != NULL)
{
cur = next;
next = cur->m_pNext;
switch (cur->m_ui8Type)
{
case PrcsdUsrCmd::SUPPORTS:
{
memcpy(ServerManager::m_pGlobalBuffer, "$Supports", 9);
uint32_t iSupportsLen = 9;
// PPK ... why dc++ have that 0 on end ? that was not in original documentation.. stupid duck...
if (((pUser->m_ui32SupportBits & User::SUPPORTBIT_ZPIPE0) == User::SUPPORTBIT_ZPIPE0) == true)
{
memcpy(ServerManager::m_pGlobalBuffer + iSupportsLen, " ZPipe0", 7);
iSupportsLen += 7;
}
else if (((pUser->m_ui32SupportBits & User::SUPPORTBIT_ZPIPE) == User::SUPPORTBIT_ZPIPE) == true)
{
memcpy(ServerManager::m_pGlobalBuffer + iSupportsLen, " ZPipe", 6);
iSupportsLen += 6;
}
// PPK ... yes yes yes finally QuickList support in PtokaX !!! ;))
if ((pUser->m_ui32SupportBits & User::SUPPORTBIT_QUICKLIST) == User::SUPPORTBIT_QUICKLIST)
{
memcpy(ServerManager::m_pGlobalBuffer + iSupportsLen, " QuickList", 10);
iSupportsLen += 10;
}
else if ((pUser->m_ui32SupportBits & User::SUPPORTBIT_NOHELLO) == User::SUPPORTBIT_NOHELLO)
{
// PPK ... Hmmm Client not really need it, but for now send it ;-)
memcpy(ServerManager::m_pGlobalBuffer + iSupportsLen, " NoHello", 8);
iSupportsLen += 8;
}
else if ((pUser->m_ui32SupportBits & User::SUPPORTBIT_NOGETINFO) == User::SUPPORTBIT_NOGETINFO)
{
// PPK ... if client support NoHello automatically supports NoGetINFO another badwith wasting !
memcpy(ServerManager::m_pGlobalBuffer + iSupportsLen, " NoGetINFO", 10);
iSupportsLen += 10;
}
#ifdef USE_FLYLINKDC_EXT_JSON
if (pUser->isSupportExtJSON())
{
memcpy(ServerManager::m_pGlobalBuffer + iSupportsLen, " ExtJSON2", 9);
iSupportsLen += 9;
}
#endif
if ((pUser->m_ui32SupportBits & User::SUPPORTBIT_HUBURL) == User::SUPPORTBIT_HUBURL)
{
memcpy(ServerManager::m_pGlobalBuffer + iSupportsLen, " HubURL", 7);
iSupportsLen += 7;
}
if ((pUser->m_ui32SupportBits & User::SUPPORTBIT_IP64) == User::SUPPORTBIT_IP64)
{
memcpy(ServerManager::m_pGlobalBuffer + iSupportsLen, " IP64", 5);
iSupportsLen += 5;
}
if (((pUser->m_ui32SupportBits & User::SUPPORTBIT_IPV4) == User::SUPPORTBIT_IPV4) && ((pUser->m_ui32BoolBits & User::BIT_IPV6) == User::BIT_IPV6))
{
// Only client connected with IPv6 sending this, so only that client is getting reply
memcpy(ServerManager::m_pGlobalBuffer + iSupportsLen, " IPv4", 5);
iSupportsLen += 5;
}
if ((pUser->m_ui32SupportBits & User::SUPPORTBIT_USERCOMMAND) == User::SUPPORTBIT_USERCOMMAND)
{
memcpy(ServerManager::m_pGlobalBuffer + iSupportsLen, " UserCommand", 12);
iSupportsLen += 12;
}
if ((pUser->m_ui32SupportBits & User::SUPPORTBIT_USERIP2) == User::SUPPORTBIT_USERIP2 && ((pUser->m_ui32BoolBits & User::BIT_QUACK_SUPPORTS) == User::BIT_QUACK_SUPPORTS) == false)
{
memcpy(ServerManager::m_pGlobalBuffer + iSupportsLen, " UserIP2", 8);
iSupportsLen += 8;
}
if ((pUser->m_ui32SupportBits & User::SUPPORTBIT_TLS2) == User::SUPPORTBIT_TLS2)
{
memcpy(ServerManager::m_pGlobalBuffer + iSupportsLen, " TLS2", 5);
iSupportsLen += 5;
}
if ((pUser->m_ui32BoolBits & User::BIT_PINGER) == User::BIT_PINGER)
{
memcpy(ServerManager::m_pGlobalBuffer + iSupportsLen, " BotINFO HubINFO", 16);
iSupportsLen += 16;
}
memcpy(ServerManager::m_pGlobalBuffer + iSupportsLen, "|\0", 2);
pUser->SendCharDelayed(ServerManager::m_pGlobalBuffer, iSupportsLen + 1);
break;
}
case PrcsdUsrCmd::LOGINHELLO:
{
pUser->SendFormat("DcCommands::ProcessCmds", true, "$Hello %s|", pUser->m_sNick);
break;
}
case PrcsdUsrCmd::GETPASS:
{
uint32_t ui32Len = 9;
pUser->SendCharDelayed("$GetPass|", ui32Len); // query user for password
break;
}
case PrcsdUsrCmd::CHAT:
{
// find chat message data
char *sBuff = cur->m_sCommand + pUser->m_ui8NickLen + 3;
// non-command chat msg
bool bNonChat = false;
for (uint8_t ui8i = 0; ui8i < (uint8_t)SettingManager::m_Ptr->m_ui16TextsLens[SETTXT_CHAT_COMMANDS_PREFIXES]; ui8i++)
{
if (sBuff[0] == SettingManager::m_Ptr->m_sTexts[SETTXT_CHAT_COMMANDS_PREFIXES][ui8i])
{
bNonChat = true;
break;
}
}
if (bNonChat == true)
{
// text files...
if (SettingManager::m_Ptr->m_bBools[SETBOOL_ENABLE_TEXT_FILES] == true)
{
cur->m_sCommand[cur->m_ui32Len - 1] = '\0'; // get rid of the pipe
if (TextFilesManager::m_Ptr->ProcessTextFilesCmd(pUser, sBuff + 1))
{
break;
}
cur->m_sCommand[cur->m_ui32Len - 1] = '|'; // add back pipe
}
// built-in commands
// alex82 ... ��������� ����������� ����� �������
if (cur->m_ui32Len - pUser->m_ui8NickLen >= 6)
{
if (HubCommands::DoCommand(pUser, sBuff - (pUser->m_ui8NickLen - 1), cur->m_ui32Len))
break;
cur->m_sCommand[cur->m_ui32Len - 1] = '|'; // add back pipe
}
}
// everything's ok, let's chat
Users::m_Ptr->SendChat2All(pUser, cur->m_sCommand, cur->m_ui32Len, cur->m_pPtr);
break;
}
case PrcsdUsrCmd::TO_OP_CHAT:
{
GlobalDataQueue::m_Ptr->SingleItemStore(cur->m_sCommand, cur->m_ui32Len, pUser, 0, GlobalDataQueue::SI_OPCHAT);
break;
}
}
safe_free(cur->m_sCommand);
delete cur;
}
pUser->m_pCmdStrt = NULL;
pUser->m_pCmdEnd = NULL;
if ((pUser->m_ui32BoolBits & User::BIT_PRCSD_MYINFO) == User::BIT_PRCSD_MYINFO)
{
pUser->m_ui32BoolBits &= ~User::BIT_PRCSD_MYINFO;
if (((pUser->m_ui32BoolBits & User::BIT_HAVE_BADTAG) == User::BIT_HAVE_BADTAG) == true)
{
pUser->HasSuspiciousTag();
}
// alex82 ... HideUser / ������� �����
if (((pUser->m_ui32InfoBits & User::INFOBIT_HIDDEN) == User::INFOBIT_HIDDEN) == false)
{
if (SettingManager::m_Ptr->m_ui8FullMyINFOOption == 0)
{
if (pUser->GenerateMyInfoLong() == false)
{
return;
}
Users::m_Ptr->Add2MyInfosTag(pUser);
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MYINFO_DELAY] == 0 || ServerManager::m_ui64ActualTick > ((60 * SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MYINFO_DELAY]) + pUser->m_ui64LastMyINFOSendTick))
{
GlobalDataQueue::m_Ptr->AddQueueItem(pUser->m_sMyInfoLong, pUser->m_ui16MyInfoLongLen, NULL, 0, GlobalDataQueue::CMD_MYINFO);
pUser->m_ui64LastMyINFOSendTick = ServerManager::m_ui64ActualTick;
}
else
{
GlobalDataQueue::m_Ptr->AddQueueItem(pUser->m_sMyInfoLong, pUser->m_ui16MyInfoLongLen, NULL, 0, GlobalDataQueue::CMD_OPS);
}
return;
}
else if (SettingManager::m_Ptr->m_ui8FullMyINFOOption == 2)
{
if (pUser->GenerateMyInfoShort() == false)
{
return;
}
Users::m_Ptr->Add2MyInfos(pUser);
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MYINFO_DELAY] == 0 || ServerManager::m_ui64ActualTick > ((60 * SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MYINFO_DELAY]) + pUser->m_ui64LastMyINFOSendTick))
{
GlobalDataQueue::m_Ptr->AddQueueItem(pUser->m_sMyInfoShort, pUser->m_ui16MyInfoShortLen, NULL, 0, GlobalDataQueue::CMD_MYINFO);
pUser->m_ui64LastMyINFOSendTick = ServerManager::m_ui64ActualTick;
}
else
{
GlobalDataQueue::m_Ptr->AddQueueItem(pUser->m_sMyInfoShort, pUser->m_ui16MyInfoShortLen, NULL, 0, GlobalDataQueue::CMD_OPS);
}
return;
}
if (pUser->GenerateMyInfoLong() == false)
{
return;
}
Users::m_Ptr->Add2MyInfosTag(pUser);
char * sShortMyINFO = NULL;
size_t szShortMyINFOLen = 0;
if (pUser->GenerateMyInfoShort() == true)
{
Users::m_Ptr->Add2MyInfos(pUser);
if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MYINFO_DELAY] == 0 || ServerManager::m_ui64ActualTick > ((60 * SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MYINFO_DELAY]) + pUser->m_ui64LastMyINFOSendTick))
{
sShortMyINFO = pUser->m_sMyInfoShort;
szShortMyINFOLen = pUser->m_ui16MyInfoShortLen;
pUser->m_ui64LastMyINFOSendTick = ServerManager::m_ui64ActualTick;
}
}
GlobalDataQueue::m_Ptr->AddQueueItem(sShortMyINFO, szShortMyINFOLen, pUser->m_sMyInfoLong, pUser->m_ui16MyInfoLongLen, GlobalDataQueue::CMD_MYINFO);
#ifdef USE_FLYLINKDC_EXT_JSON
if ((pUser->m_ui32BoolBits & User::BIT_PRCSD_EXT_JSON) == User::BIT_PRCSD_EXT_JSON)
{
pUser->m_ui32BoolBits &= ~User::BIT_PRCSD_EXT_JSON;
// TODO ExtJSON - ????? Users::m_Ptr->Add2MyInfosTag(pUser);
if (pUser->isSupportExtJSON())
{
if (pUser->m_user_ext_info)
{
const std::string l_ext_json_info = pUser->m_user_ext_info->GetExtJSONCommand();
if (!l_ext_json_info.empty())
{
// TODO ExtJSON if (SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MYINFO_DELAY] == 0 || ServerManager::m_ui64ActualTick > ((60 * SettingManager::m_Ptr->m_i16Shorts[SETSHORT_MYINFO_DELAY]) + pUser->getLastExtJSONSendTick()))
if (pUser->getLastExtJSONSendTick() || ServerManager::m_ui64ActualTick > pUser->getLastExtJSONSendTick() + 60)
{
GlobalDataQueue::m_Ptr->AddQueueItem(l_ext_json_info.c_str(), l_ext_json_info.size(), NULL, 0, GlobalDataQueue::CMD_EXTJSON);
pUser->setLastExtJSONSendTick(ServerManager::m_ui64ActualTick);
}
else
{
GlobalDataQueue::m_Ptr->AddQueueItem(l_ext_json_info.c_str(), l_ext_json_info.size(), NULL, 0, GlobalDataQueue::CMD_OPS);
}
}
}
}
}
#endif // USE_FLYLINKDC_EXT_JSON
} // HideUser
} // MyINFO
}
//---------------------------------------------------------------------------
static bool CheckPort(char * sData, char cPortEnd)
{
for (uint8_t ui8i = 0; ui8i < 6; ui8i++)
{
if (isdigit(sData[ui8i]) != 0)
{
continue;
// alex82 ... NAT Traversal fix by Pavel Pimenov
}
else if (sData[ui8i] == cPortEnd ||
(cPortEnd == '|' && sData[ui8i] == 'S' && sData[ui8i + 1] == cPortEnd) ||
(sData[ui8i] == 'N' && (sData[ui8i + 1] == 'S' || sData[ui8i + 1] == ' ')) ||
(sData[ui8i] == 'R' && (sData[ui8i + 1] == 'S' || sData[ui8i + 1] == '|')))
{
const char cEnd = sData[ui8i];
sData[ui8i] = '\0';
const int iPort = atoi(sData);
if (ui8i != 0 && iPort > 0 && iPort < 65536)
{
sData[ui8i] = cEnd;
return false;
}
else
{
sData[ui8i] = cEnd;
}
}
break;
}
return true;
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void DcCommands::MyNick(DcCommand * pDcCommand)
{
if ((pDcCommand->m_pUser->m_ui32BoolBits & User::BIT_IPV6) == User::BIT_IPV6)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] IPv6 $MyNick (%s) from %s (%s) - user closed.", pDcCommand->m_sCommand, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
Unknown(pDcCommand, true);
return;
}
if (pDcCommand->m_ui32CommandLen < 10)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Short $MyNick (%s) from %s (%s) - user closed.", pDcCommand->m_sCommand, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
Unknown(pDcCommand, true);
return;
}
pDcCommand->m_sCommand[pDcCommand->m_ui32CommandLen - 1] = '\0'; // cutoff pipe
User * pOtherUser = HashManager::m_Ptr->FindUser(pDcCommand->m_sCommand + 8, pDcCommand->m_ui32CommandLen - 9);
if (pOtherUser == NULL || pOtherUser->m_ui8State != User::STATE_IPV4_CHECK)
{
UdpDebug::m_Ptr->BroadcastFormat("[SYS] Bad $MyNick (%s) from %s (%s) - user closed.", pDcCommand->m_sCommand, pDcCommand->m_pUser->m_sNick, pDcCommand->m_pUser->m_sIP);
Unknown(pDcCommand, true);
return;
}
strncpy(pOtherUser->m_sIPv4, pDcCommand->m_pUser->m_sIP,sizeof(pOtherUser->m_sIPv4));
pOtherUser->m_sIPv4[sizeof(pOtherUser->m_sIPv4)-1] = 0;
pOtherUser->m_ui8IPv4Len = pDcCommand->m_pUser->m_ui8IpLen;
pOtherUser->m_ui32BoolBits |= User::BIT_IPV4;
pOtherUser->m_ui8State = User::STATE_ADDME;
pDcCommand->m_pUser->Close();
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
uint16_t DcCommands::CheckAndGetPort(char * pPort, const uint8_t ui8PortLen, uint32_t &ui32PortLen)
{
uint8_t ui8Index = ui8PortLen - 1;
while (true)
{
if (pPort[ui8Index] == ':')
{
// We have something which looks like port.. return values
ui32PortLen = (ui8PortLen - ui8Index) - 1;
return (uint16_t)atoi((pPort + ui8Index) + 1);
}
else if (isdigit(pPort[ui8Index]) == 0)
{
// It is not : and it is not number... this port is not valid
return 0;
}
if (ui8Index == 0)
{
break;
}
ui8Index--;
}
// Valid port not found
return 0;
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void DcCommands::SendIPFixedMsg(User * pUser, char * pBadIP, char * pRealIP)
{
if ((pUser->m_ui32BoolBits & User::BIT_WARNED_WRONG_IP) == User::BIT_WARNED_WRONG_IP)
{
return;
}
pUser->SendFormat("DcCommands::SendIPFixedMsg", true, "<%s> %s '%s' %s %s !|", SettingManager::m_Ptr->m_sPreTexts[SettingManager::SETPRETXT_HUB_SEC], LanguageManager::m_Ptr->m_sTexts[LAN_YOUR_CLIENT_SEND_INCORRECT_IP], pBadIP,
LanguageManager::m_Ptr->m_sTexts[LAN_IN_COMMAND_HUB_REPLACED_IT_WITH_YOUR_REAL_IP], pRealIP);
pUser->m_ui32BoolBits |= User::BIT_WARNED_WRONG_IP;
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
PrcsdUsrCmd * DcCommands::AddSearch(User * pUser, PrcsdUsrCmd * pCmdSearch, char * sSearch, const size_t szLen, const bool bActive)
{
if (pCmdSearch != NULL)
{
char * pOldBuf = pCmdSearch->m_sCommand;
pCmdSearch->m_sCommand = (char *)realloc(pOldBuf, pCmdSearch->m_ui32Len + szLen + 1);
if (pCmdSearch->m_sCommand == NULL)
{
pCmdSearch->m_sCommand = pOldBuf;
pUser->m_ui32BoolBits |= User::BIT_ERROR;
pUser->Close();
AppendDebugLogFormat("[MEM] Cannot reallocate %zu bytes for DcCommands::AddSearch1\n", pCmdSearch->m_ui32Len+szLen+1);
return pCmdSearch;
}
memcpy(pCmdSearch->m_sCommand + pCmdSearch->m_ui32Len, sSearch, szLen);
pCmdSearch->m_ui32Len += (uint32_t)szLen;
pCmdSearch->m_sCommand[pCmdSearch->m_ui32Len] = '\0';
if (bActive == true)
{
Users::m_Ptr->m_ui16ActSearchs++;
}
else
{
Users::m_Ptr->m_ui16PasSearchs++;
}
}
else
{
pCmdSearch = new (std::nothrow) PrcsdUsrCmd();
if (pCmdSearch == NULL)
{
pUser->m_ui32BoolBits |= User::BIT_ERROR;
pUser->Close();
AppendDebugLog("%s - [MEM] Cannot allocate new pCmdSearch in DcCommands::AddSearch1\n");
return pCmdSearch;
}
pCmdSearch->m_sCommand = (char *)malloc(szLen + 1);
if (pCmdSearch->m_sCommand == NULL)
{
delete pCmdSearch;
pUser->m_ui32BoolBits |= User::BIT_ERROR;
pUser->Close();
AppendDebugLogFormat("[MEM] Cannot allocate %zu bytes for DcCommands::Search5\n", szLen+1);
return NULL;
}
memcpy(pCmdSearch->m_sCommand, sSearch, szLen);
pCmdSearch->m_sCommand[szLen] = '\0';
pCmdSearch->m_ui32Len = (uint32_t)szLen;
if (bActive == true)
{
Users::m_Ptr->m_ui16ActSearchs++;
}
else
{
Users::m_Ptr->m_ui16PasSearchs++;
}
}
return pCmdSearch;
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
↑ V1042 This file is marked with copyleft license, which requires you to open the derived source code.
↑ V1065 Expression can be simplified, check 'ui32IpPortLen' and similar operands.
↑ V1065 Expression can be simplified, check 'ui32IpPortLen' and similar operands.
↑ V1065 Expression can be simplified, check 'iAfterCmd' and similar operands.
↑ V1065 Expression can be simplified, check 'ui32IpPortLen' and similar operands.
↑ V1032 The pointer '"ulti"' is cast to a more strictly aligned pointer type.
↑ V1032 The pointer '"ick "' is cast to a more strictly aligned pointer type.
↑ V1032 The pointer '"Key "' is cast to a more strictly aligned pointer type.
↑ V1032 The pointer '"R "' is cast to a more strictly aligned pointer type.
↑ V1032 The pointer '"et"' is cast to a more strictly aligned pointer type.
↑ V1032 The pointer '"NickList"' is cast to a more strictly aligned pointer type.
↑ V1032 The pointer '"Hub:"' is cast to a more strictly aligned pointer type.
↑ V1032 The pointer '"uickList"' is cast to a more strictly aligned pointer type.
↑ V1032 The pointer '"Pipe"' is cast to a more strictly aligned pointer type.
↑ V1032 The pointer '"IP64"' is cast to a more strictly aligned pointer type.
↑ V1032 The pointer '"IPv4"' is cast to a more strictly aligned pointer type.
↑ V1032 The pointer '"TLS2"' is cast to a more strictly aligned pointer type.