From 084988a3078f51e794ea743669e8fde2babff95e Mon Sep 17 00:00:00 2001 From: psychon Date: Sat, 1 May 2010 14:33:15 +0000 Subject: [PATCH] Add and use CListener::AcceptType This enum let's one control what kind of connections a listener will allow. HTTP requests to an IRC-only port and IRC requests to a HTTP-only port will be booted off. git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@1960 726aef4b-f618-498e-8847-2d620e286838 --- Listener.cpp | 38 ++++++++++++++++---- Listener.h | 100 +++++++++++++++++++++++++++++---------------------- 2 files changed, 88 insertions(+), 50 deletions(-) diff --git a/Listener.cpp b/Listener.cpp index d98818db..8fc39fb4 100644 --- a/Listener.cpp +++ b/Listener.cpp @@ -27,6 +27,11 @@ bool CListener::Listen() { m_pListener, 0, m_eAddr); } +CListener::~CListener() { + if (m_pListener) + CZNC::Get().GetManager().DelSockByAddr(m_pListener); +} + CRealListener::~CRealListener() { m_pParent->SetRealListener(NULL); } @@ -38,7 +43,7 @@ bool CRealListener::ConnectionFrom(const CString& sHost, unsigned short uPort) { } Csock* CRealListener::GetSockObj(const CString& sHost, unsigned short uPort) { - CIncomingConnection *pClient = new CIncomingConnection(sHost, uPort); + CIncomingConnection *pClient = new CIncomingConnection(sHost, uPort, m_pParent->GetAcceptType()); if (CZNC::Get().AllowConnectionFrom(sHost)) { CZNC::Get().GetModules().OnClientConnect(pClient, sHost, uPort); } else { @@ -58,7 +63,8 @@ void CRealListener::SockError(int iErrno) { } } -CIncomingConnection::CIncomingConnection(const CString& sHostname, unsigned short uPort) : CZNCSock(sHostname, uPort) { +CIncomingConnection::CIncomingConnection(const CString& sHostname, unsigned short uPort, CListener::AcceptType eAcceptType) : CZNCSock(sHostname, uPort) { + m_eAcceptType = eAcceptType; // The socket will time out in 120 secs, no matter what. // This has to be fixed up later, if desired. SetTimeout(120, 0); @@ -68,11 +74,23 @@ CIncomingConnection::CIncomingConnection(const CString& sHostname, unsigned shor void CIncomingConnection::ReadLine(const CString& sLine) { bool bIsHTTP = (sLine.WildCmp("GET * HTTP/1.?\r\n") || sLine.WildCmp("POST * HTTP/1.?\r\n")); + bool bAcceptHTTP = (m_eAcceptType == CListener::ACCEPT_ALL) + || (m_eAcceptType == CListener::ACCEPT_HTTP); + bool bAcceptIRC = (m_eAcceptType == CListener::ACCEPT_ALL) + || (m_eAcceptType == CListener::ACCEPT_IRC); Csock *pSock = NULL; if (!bIsHTTP) { // Let's assume it's an IRC connection + if (!bAcceptIRC) { + Write("ERROR :We don't take kindly to your types around here!\r\n"); + Close(CLT_AFTERWRITE); + + DEBUG("Refused IRC connection to non IRC port"); + return; + } + pSock = new CClient(); CZNC::Get().GetManager().SwapSockByAddr(pSock, this); @@ -81,6 +99,14 @@ void CIncomingConnection::ReadLine(const CString& sLine) { } else { // This is a HTTP request, let the webmods handle it + if (!bAcceptHTTP) { + Write("HTTP/1.0 403 Access Denied\r\n\r\nNo HTTP requests allowed\r\n"); + Close(CLT_AFTERWRITE); + + DEBUG("Refused HTTP connection to non HTTP port"); + return; + } + CModule* pMod = new CModule(NULL, "", ""); pMod->SetFake(true); @@ -91,9 +117,7 @@ void CIncomingConnection::ReadLine(const CString& sLine) { pSock->SetSockName("WebMod::Client"); } - if (pSock) { - // TODO can we somehow get rid of this? - pSock->ReadLine(sLine); - pSock->PushBuff("", 0, true); - } + // TODO can we somehow get rid of this? + pSock->ReadLine(sLine); + pSock->PushBuff("", 0, true); } diff --git a/Listener.h b/Listener.h index 5c220d5f..c849a453 100644 --- a/Listener.h +++ b/Listener.h @@ -11,6 +11,59 @@ #include "znc.h" +// Forward Declarations +class CRealListener; +// !Forward Declarations + +class CListener { +public: + typedef enum { + ACCEPT_IRC, + ACCEPT_HTTP, + ACCEPT_ALL + } AcceptType; + + CListener(unsigned short uPort, const CString& sBindHost, bool bSSL, EAddrType eAddr) { + m_uPort = uPort; + m_sBindHost = sBindHost; + m_bSSL = bSSL; + m_eAddr = eAddr; + m_pListener = NULL; + m_eAcceptType = ACCEPT_ALL; + } + + ~CListener(); + + // Setters + void SetSSL(bool b) { m_bSSL = b; } + void SetAddrType(EAddrType eAddr) { m_eAddr = eAddr; } + void SetPort(unsigned short u) { m_uPort = u; } + void SetBindHost(const CString& s) { m_sBindHost = s; } + void SetRealListener(CRealListener* p) { m_pListener = p; } + void SetAcceptType(AcceptType a) { m_eAcceptType = a; } + // !Setters + + // Getters + bool IsSSL() const { return m_bSSL; } + EAddrType GetAddrType() const { return m_eAddr; } + unsigned short GetPort() const { return m_uPort; } + const CString& GetBindHost() const { return m_sBindHost; } + CRealListener* GetRealListener() const { return m_pListener; } + AcceptType GetAcceptType() const { return m_eAcceptType; } + // !Getters + + bool Listen(); + +private: +protected: + bool m_bSSL; + EAddrType m_eAddr; + unsigned short m_uPort; + CString m_sBindHost; + CRealListener* m_pListener; + AcceptType m_eAcceptType; +}; + class CRealListener : public CZNCSock { public: CRealListener(CListener *pParent) : CZNCSock(), m_pParent(pParent) {} @@ -24,53 +77,14 @@ private: CListener* m_pParent; }; -class CListener { -public: - CListener(unsigned short uPort, const CString& sBindHost, bool bSSL, EAddrType eAddr) { - m_uPort = uPort; - m_sBindHost = sBindHost; - m_bSSL = bSSL; - m_eAddr = eAddr; - m_pListener = NULL; - } - - ~CListener() { - if (m_pListener) - CZNC::Get().GetManager().DelSockByAddr(m_pListener); - } - - // Setters - void SetSSL(bool b) { m_bSSL = b; } - void SetAddrType(EAddrType eAddr) { m_eAddr = eAddr; } - void SetPort(unsigned short u) { m_uPort = u; } - void SetBindHost(const CString& s) { m_sBindHost = s; } - void SetRealListener(CRealListener* p) { m_pListener = p; } - // !Setters - - // Getters - bool IsSSL() const { return m_bSSL; } - EAddrType GetAddrType() const { return m_eAddr; } - unsigned short GetPort() const { return m_uPort; } - const CString& GetBindHost() const { return m_sBindHost; } - CRealListener* GetRealListener() const { return m_pListener; } - // !Getters - - bool Listen(); - -private: -protected: - bool m_bSSL; - EAddrType m_eAddr; - unsigned short m_uPort; - CString m_sBindHost; - CRealListener* m_pListener; -}; - class CIncomingConnection : public CZNCSock { public: - CIncomingConnection(const CString& sHostname, unsigned short uPort); + CIncomingConnection(const CString& sHostname, unsigned short uPort, CListener::AcceptType eAcceptType); virtual ~CIncomingConnection() {} virtual void ReadLine(const CString& sData); + +private: + CListener::AcceptType m_eAcceptType; }; #endif // !_LISTENER_H