mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
commit
5a29fa8fca
|
@ -166,6 +166,7 @@ public:
|
|||
|
||||
virtual int* GetIdMap(int ClientID) = 0;
|
||||
|
||||
virtual bool DnsblWhite(int ClientID) = 0;
|
||||
};
|
||||
|
||||
class IGameServer : public IInterface
|
||||
|
|
|
@ -800,6 +800,9 @@ int CServer::ClientRejoinCallback(int ClientID, void *pUser)
|
|||
int CServer::NewClientNoAuthCallback(int ClientID, bool Reset, void *pUser)
|
||||
{
|
||||
CServer *pThis = (CServer *)pUser;
|
||||
|
||||
pThis->m_aClients[ClientID].m_DnsblState = CClient::DNSBL_STATE_NONE;
|
||||
|
||||
if (Reset)
|
||||
{
|
||||
pThis->m_aClients[ClientID].m_State = CClient::STATE_CONNECTING;
|
||||
|
@ -821,6 +824,7 @@ int CServer::NewClientCallback(int ClientID, void *pUser)
|
|||
{
|
||||
CServer *pThis = (CServer *)pUser;
|
||||
pThis->m_aClients[ClientID].m_State = CClient::STATE_AUTH;
|
||||
pThis->m_aClients[ClientID].m_DnsblState = CClient::DNSBL_STATE_NONE;
|
||||
pThis->m_aClients[ClientID].m_aName[0] = 0;
|
||||
pThis->m_aClients[ClientID].m_aClan[0] = 0;
|
||||
pThis->m_aClients[ClientID].m_Country = -1;
|
||||
|
@ -834,6 +838,27 @@ int CServer::NewClientCallback(int ClientID, void *pUser)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void CServer::InitDnsbl(int ClientID)
|
||||
{
|
||||
NETADDR Addr = *m_NetServer.ClientAddr(ClientID);
|
||||
|
||||
//TODO: support ipv6
|
||||
if (Addr.type != NETTYPE_IPV4)
|
||||
return;
|
||||
|
||||
// build dnsbl host lookup
|
||||
char aBuf[256];
|
||||
if (g_Config.m_SvDnsblKey[0] == '\0')
|
||||
// without key
|
||||
str_format(aBuf, sizeof(aBuf), "%d.%d.%d.%d.%s", Addr.ip[3], Addr.ip[2], Addr.ip[1], Addr.ip[0], g_Config.m_SvDnsblHost);
|
||||
else
|
||||
// with key
|
||||
str_format(aBuf, sizeof(aBuf), "%s.%d.%d.%d.%d.%s", g_Config.m_SvDnsblKey, Addr.ip[3], Addr.ip[2], Addr.ip[1], Addr.ip[0], g_Config.m_SvDnsblHost);
|
||||
|
||||
IEngine *pEngine = Kernel()->RequestInterface<IEngine>();
|
||||
pEngine->HostLookup(&m_aClients[ClientID].m_DnsblLookup, aBuf, NETTYPE_IPV4);
|
||||
}
|
||||
|
||||
int CServer::DelClientCallback(int ClientID, const char *pReason, void *pUser)
|
||||
{
|
||||
CServer *pThis = (CServer *)pUser;
|
||||
|
@ -1742,6 +1767,50 @@ int CServer::Run()
|
|||
}
|
||||
}
|
||||
|
||||
// handle dnsbl
|
||||
if (g_Config.m_SvDnsbl)
|
||||
{
|
||||
for (int c = 0; c < MAX_CLIENTS; c++)
|
||||
{
|
||||
if (m_aClients[c].m_State == CClient::STATE_EMPTY)
|
||||
continue;
|
||||
|
||||
if (m_aClients[c].m_DnsblState == CClient::DNSBL_STATE_NONE)
|
||||
{
|
||||
// initiate dnsbl lookup
|
||||
m_aClients[c].m_DnsblState = CClient::DNSBL_STATE_PENDING;
|
||||
InitDnsbl(c);
|
||||
}
|
||||
else if (m_aClients[c].m_DnsblState == CClient::DNSBL_STATE_PENDING &&
|
||||
m_aClients[c].m_DnsblLookup.m_Job.Status() == CJob::STATE_DONE)
|
||||
{
|
||||
|
||||
if (m_aClients[c].m_DnsblLookup.m_Addr.type == NETTYPE_INVALID)
|
||||
{
|
||||
// entry not found -> whitelisted
|
||||
m_aClients[c].m_DnsblState = CClient::DNSBL_STATE_WHITELISTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
// entry found -> blacklisted
|
||||
m_aClients[c].m_DnsblState = CClient::DNSBL_STATE_BLACKLISTED;
|
||||
|
||||
// console output
|
||||
char aAddrStr[NETADDR_MAXSTRSIZE];
|
||||
net_addr_str(m_NetServer.ClientAddr(c), aAddrStr, sizeof(aAddrStr), true);
|
||||
|
||||
char aBuf[256];
|
||||
str_format(aBuf, sizeof(aBuf), "ClientID=%d addr=%s secure=%s blacklisted", c, aAddrStr, m_NetServer.HasSecurityToken(c)?"yes":"no");
|
||||
Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "dnsbl", aBuf);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_aClients[c].m_DnsblState == CClient::DNSBL_STATE_BLACKLISTED &&
|
||||
g_Config.m_SvDnsblBan)
|
||||
m_NetServer.NetBan()->BanAddr(m_NetServer.ClientAddr(c), 60*10, "Blacklisted by DNSBL");
|
||||
}
|
||||
}
|
||||
|
||||
while(t > TickStartTime(m_CurrentGameTick+1))
|
||||
{
|
||||
m_CurrentGameTick++;
|
||||
|
@ -1905,6 +1974,34 @@ void CServer::ConStatus(IConsole::IResult *pResult, void *pUser)
|
|||
}
|
||||
}
|
||||
|
||||
void CServer::ConDnsblStatus(IConsole::IResult *pResult, void *pUser)
|
||||
{
|
||||
// dump blacklisted clients
|
||||
char aBuf[1024];
|
||||
char aAddrStr[NETADDR_MAXSTRSIZE];
|
||||
CServer* pThis = static_cast<CServer *>(pUser);
|
||||
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
if(pThis->m_aClients[i].m_State != CClient::STATE_EMPTY &&
|
||||
pThis->m_aClients[i].m_DnsblState == CClient::DNSBL_STATE_BLACKLISTED)
|
||||
{
|
||||
net_addr_str(pThis->m_NetServer.ClientAddr(i), aAddrStr, sizeof(aAddrStr), true);
|
||||
if(pThis->m_aClients[i].m_State == CClient::STATE_INGAME)
|
||||
{
|
||||
const char *pAuthStr = pThis->m_aClients[i].m_Authed == CServer::AUTHED_ADMIN ? "(Admin)" :
|
||||
pThis->m_aClients[i].m_Authed == CServer::AUTHED_MOD ? "(Mod)" :
|
||||
pThis->m_aClients[i].m_Authed == CServer::AUTHED_HELPER ? "(Helper)" : "";
|
||||
str_format(aBuf, sizeof(aBuf), "id=%d addr=%s name='%s' score=%d client=%d secure=%s %s", i, aAddrStr,
|
||||
pThis->m_aClients[i].m_aName, pThis->m_aClients[i].m_Score, ((CGameContext *)(pThis->GameServer()))->m_apPlayers[i]->m_ClientVersion, pThis->m_NetServer.HasSecurityToken(i) ? "yes":"no", pAuthStr);
|
||||
}
|
||||
else
|
||||
str_format(aBuf, sizeof(aBuf), "id=%d addr=%s connecting", i, aAddrStr);
|
||||
pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", aBuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CServer::ConShutdown(IConsole::IResult *pResult, void *pUser)
|
||||
{
|
||||
((CServer *)pUser)->m_RunServer = 0;
|
||||
|
@ -2240,6 +2337,8 @@ void CServer::RegisterCommands()
|
|||
|
||||
#endif
|
||||
|
||||
Console()->Register("dnsbl_status", "", CFGFLAG_SERVER, ConDnsblStatus, this, "List blacklisted players");
|
||||
|
||||
Console()->Chain("sv_name", ConchainSpecialInfoupdate, this);
|
||||
Console()->Chain("password", ConchainSpecialInfoupdate, this);
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#ifndef ENGINE_SERVER_SERVER_H
|
||||
#define ENGINE_SERVER_SERVER_H
|
||||
|
||||
#include <engine/engine.h>
|
||||
#include <engine/server.h>
|
||||
|
||||
#include <engine/map.h>
|
||||
|
@ -116,7 +117,12 @@ public:
|
|||
|
||||
SNAPRATE_INIT=0,
|
||||
SNAPRATE_FULL,
|
||||
SNAPRATE_RECOVER
|
||||
SNAPRATE_RECOVER,
|
||||
|
||||
DNSBL_STATE_NONE=0,
|
||||
DNSBL_STATE_PENDING,
|
||||
DNSBL_STATE_BLACKLISTED,
|
||||
DNSBL_STATE_WHITELISTED,
|
||||
};
|
||||
|
||||
class CInput
|
||||
|
@ -156,6 +162,10 @@ public:
|
|||
// DDRace
|
||||
|
||||
NETADDR m_Addr;
|
||||
|
||||
// DNSBL
|
||||
int m_DnsblState;
|
||||
CHostLookup m_DnsblLookup;
|
||||
};
|
||||
|
||||
CClient m_aClients[MAX_CLIENTS];
|
||||
|
@ -282,6 +292,7 @@ public:
|
|||
static void ConStopRecord(IConsole::IResult *pResult, void *pUser);
|
||||
static void ConMapReload(IConsole::IResult *pResult, void *pUser);
|
||||
static void ConLogout(IConsole::IResult *pResult, void *pUser);
|
||||
static void ConDnsblStatus(IConsole::IResult *pResult, void *pUser);
|
||||
|
||||
#if defined (CONF_SQL)
|
||||
// console commands for sqlmasters
|
||||
|
@ -320,6 +331,12 @@ public:
|
|||
|
||||
virtual int* GetIdMap(int ClientID);
|
||||
|
||||
void InitDnsbl(int ClientID);
|
||||
bool DnsblWhite(int ClientID)
|
||||
{
|
||||
return m_aClients[ClientID].m_DnsblState == CClient::DNSBL_STATE_NONE ||
|
||||
m_aClients[ClientID].m_DnsblState == CClient::DNSBL_STATE_WHITELISTED;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -150,6 +150,12 @@ MACRO_CONFIG_INT(SvRconBantime, sv_rcon_bantime, 5, 0, 1440, CFGFLAG_SERVER, "Th
|
|||
MACRO_CONFIG_INT(SvAutoDemoRecord, sv_auto_demo_record, 0, 0, 1, CFGFLAG_SERVER, "Automatically record demos")
|
||||
MACRO_CONFIG_INT(SvAutoDemoMax, sv_auto_demo_max, 10, 0, 1000, CFGFLAG_SERVER, "Maximum number of automatically recorded demos (0 = no limit)")
|
||||
MACRO_CONFIG_INT(SvVanillaAntiSpoof, sv_vanilla_antispoof, 1, 0, 1, CFGFLAG_SERVER, "Enable vanilla Antispoof")
|
||||
MACRO_CONFIG_INT(SvDnsbl, sv_dnsbl, 0, 0, 1, CFGFLAG_SERVER, "Enable DNSBL (DNS-based Blackhole List)")
|
||||
MACRO_CONFIG_STR(SvDnsblHost, sv_dnsbl_host, 128, "", CFGFLAG_SERVER, "Hostname of DNSBL provider to use for IP Verification")
|
||||
MACRO_CONFIG_STR(SvDnsblKey, sv_dnsbl_key, 128, "", CFGFLAG_SERVER, "Optional Authentification Key for the specified DNSBL provider")
|
||||
MACRO_CONFIG_INT(SvDnsblVote, sv_dnsbl_vote, 0, 0, 1, CFGFLAG_SERVER, "Block votes by blacklisted addresses")
|
||||
MACRO_CONFIG_INT(SvDnsblBan, sv_dnsbl_ban, 0, 0, 1, CFGFLAG_SERVER, "Automatically ban blacklisted addresses")
|
||||
|
||||
|
||||
MACRO_CONFIG_INT(SvPlayerDemoRecord, sv_player_demo_record, 0, 0, 1, CFGFLAG_SERVER, "Automatically record demos for each player")
|
||||
MACRO_CONFIG_INT(SvDemoChat, sv_demo_chat, 0, 0, 1, CFGFLAG_SERVER, "Record chat for demos")
|
||||
|
|
|
@ -653,6 +653,10 @@ void CGameContext::OnTick()
|
|||
if(m_apPlayers[i]->m_Afk && i != m_VoteCreator)
|
||||
continue;
|
||||
|
||||
// don't count votes by blacklisted clients
|
||||
if (g_Config.m_SvDnsblVote && !m_pServer->DnsblWhite(i))
|
||||
continue;
|
||||
|
||||
int ActVote = m_apPlayers[i]->m_Vote;
|
||||
int ActVotePos = m_apPlayers[i]->m_VotePos;
|
||||
|
||||
|
@ -1151,6 +1155,13 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID)
|
|||
int64 Now = Server()->Tick();
|
||||
int64 TickSpeed = Server()->TickSpeed();
|
||||
|
||||
if (g_Config.m_SvDnsblVote && !m_pServer->DnsblWhite(ClientID))
|
||||
{
|
||||
// blacklisted by dnsbl
|
||||
SendChatTarget(ClientID, "You are not allowed to vote due to DNSBL");
|
||||
return;
|
||||
}
|
||||
|
||||
if(g_Config.m_SvSpamprotection && pPlayer->m_LastVoteTry && pPlayer->m_LastVoteTry + TickSpeed * 3 > Now)
|
||||
return;
|
||||
|
||||
|
|
Loading…
Reference in a new issue