mirror of
https://github.com/znc/znc.git
synced 2026-05-04 04:22:37 +02:00
Add a limit of 10 unidentified connections per IP
Everything which isn't a CClient with a successful login counts as an unidentified connection in this context. Modules who don't want this kind of limit on their listening sockets can override CSocket::ConnectionFrom(), but their sockets will still count towards this limit. git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@1561 726aef4b-f618-498e-8847-2d620e286838
This commit is contained in:
2
Client.h
2
Client.h
@@ -85,6 +85,8 @@ public:
|
||||
SetMaxBufferThreshold(1024);
|
||||
|
||||
StartLoginTimeout();
|
||||
|
||||
SetNick("unknown-nick");
|
||||
}
|
||||
|
||||
virtual ~CClient();
|
||||
|
||||
@@ -145,6 +145,10 @@ void CSocket::SockError(int iErrno) {
|
||||
}
|
||||
}
|
||||
|
||||
bool CSocket::ConnectionFrom(const CString& sHost, unsigned short uPort) {
|
||||
return CZNC::Get().AllowConnectionFrom(sHost);
|
||||
}
|
||||
|
||||
bool CSocket::Connect(const CString& sHostname, unsigned short uPort, bool bSSL, unsigned int uTimeout) {
|
||||
CUser* pUser = m_pModule->GetUser();
|
||||
CString sSockName = "MOD::C::" + m_pModule->GetModName();
|
||||
|
||||
@@ -151,6 +151,9 @@ public:
|
||||
// This defaults to closing the socket, feel free to override
|
||||
virtual void ReachedMaxBuffer();
|
||||
virtual void SockError(int iErrno);
|
||||
// This limits the global connections from this IP to defeat DoS
|
||||
// attacks, feel free to override
|
||||
virtual bool ConnectionFrom(const CString& sHost, unsigned short uPort);
|
||||
|
||||
bool Connect(const CString& sHostname, unsigned short uPort, bool bSSL = false, unsigned int uTimeout = 60);
|
||||
bool Listen(unsigned short uPort, bool bSSL = false, unsigned int uTimeout = 0);
|
||||
|
||||
17
Socket.cpp
17
Socket.cpp
@@ -191,3 +191,20 @@ int CZNCSock::GetAddrInfo(const CS_STRING &sHostname, CSSockAddr &csSockAddr) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned int CSockManager::GetAnonConnectionCount(const CString &sIP) const {
|
||||
const_iterator it;
|
||||
unsigned int ret = 0;
|
||||
|
||||
for (it = begin(); it != end(); it++) {
|
||||
CZNCSock *pSock = *it;
|
||||
// Logged in CClients have "USR::<username>" as their sockname
|
||||
if (pSock->GetRemoteIP() == sIP && pSock->GetSockName().Left(5) != "USR::") {
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG("There are [" << ret << "] clients from [" << sIP << "]");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
2
Socket.h
2
Socket.h
@@ -98,6 +98,8 @@ public:
|
||||
|
||||
return TSocketManager<CZNCSock>::Connect(C, pcSock);
|
||||
}
|
||||
|
||||
unsigned int GetAnonConnectionCount(const CString &sIP) const;
|
||||
private:
|
||||
protected:
|
||||
#ifdef HAVE_ARES
|
||||
|
||||
6
znc.cpp
6
znc.cpp
@@ -399,6 +399,12 @@ bool CZNC::IsHostAllowed(const CString& sHostMask) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CZNC::AllowConnectionFrom(const CString& sIP) const {
|
||||
if (GetManager().GetAnonConnectionCount(sIP) >= 10)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CZNC::InitDirs(const CString& sArgvPath, const CString& sDataDir) {
|
||||
char *home;
|
||||
|
||||
|
||||
12
znc.h
12
znc.h
@@ -37,6 +37,8 @@ public:
|
||||
CUser* GetUser(const CString& sUser);
|
||||
Csock* FindSockByName(const CString& sSockName);
|
||||
bool IsHostAllowed(const CString& sHostMask) const;
|
||||
// This returns false if there are too many anonymous connections from this ip
|
||||
bool AllowConnectionFrom(const CString& sIP) const;
|
||||
void InitDirs(const CString& sArgvPath, const CString& sDataDir);
|
||||
bool OnBoot();
|
||||
CString ExpandConfigPath(const CString& sConfigFile);
|
||||
@@ -86,6 +88,7 @@ public:
|
||||
// Getters
|
||||
bool GetNeedRehash() const { return m_bNeedRehash; }
|
||||
CSockManager& GetManager() { return m_Manager; }
|
||||
const CSockManager& GetManager() const { return m_Manager; }
|
||||
#ifdef _MODULES
|
||||
CGlobalModules& GetModules() { return *m_pModules; }
|
||||
#endif
|
||||
@@ -175,9 +178,16 @@ public:
|
||||
|
||||
virtual Csock* GetSockObj(const CString& sHost, unsigned short uPort) {
|
||||
CClient *pClient = new CClient(sHost, uPort);
|
||||
if (CZNC::Get().AllowConnectionFrom(sHost))
|
||||
#ifdef _MODULES
|
||||
CZNC::Get().GetModules().OnClientConnect(pClient, sHost, uPort);
|
||||
CZNC::Get().GetModules().OnClientConnect(pClient, sHost, uPort);
|
||||
#endif
|
||||
else {
|
||||
pClient->RefuseLogin("Too many anonymous connections from your IP");
|
||||
#ifdef _MODULES
|
||||
CZNC::Get().GetModules().OnFailedLogin("", sHost);
|
||||
#endif
|
||||
}
|
||||
return pClient;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user