diff --git a/include/znc/Listener.h b/include/znc/Listener.h index d8e43185..383547a2 100644 --- a/include/znc/Listener.h +++ b/include/znc/Listener.h @@ -57,7 +57,7 @@ class CListener { private: protected: - void setupSSL(CRealListener* listener) const; + void SetupSSL() const; bool m_bSSL; CString m_sURIPrefix; diff --git a/include/znc/znc.h b/include/znc/znc.h index ef3eb2dd..27b851de 100644 --- a/include/znc/znc.h +++ b/include/znc/znc.h @@ -277,6 +277,8 @@ class CZNC : private CCoreTranslationMixin { CString MakeConfigHeader(); bool AddListener(const CString& sLine, CString& sError); bool AddListener(CConfig* pConfig, CString& sError); + bool CheckSslAndPemFile(bool bSSL, CString& sError); + bool FinishAddingListener(CListener* pListener, CString& sError); protected: time_t m_TimeStarted; diff --git a/src/Listener.cpp b/src/Listener.cpp index 71bdbb18..2d37589f 100644 --- a/src/Listener.cpp +++ b/src/Listener.cpp @@ -39,7 +39,7 @@ CConfig CListener::ToConfig() const { return listenerConfig; } -void CListener::setupSSL(CRealListener* listener) const { +void CListener::SetupSSL() const { #ifdef HAVE_LIBSSL if (IsSSL()) { m_pListener->SetSSL(true); @@ -60,19 +60,14 @@ bool CTCPListener::Listen() { } m_pListener = new CRealListener(*this); - - setupSSL(m_pListener); - bool bSSL = false; -#ifdef HAVE_LIBSSL - bSSL = IsSSL(); -#endif + SetupSSL(); // If e.g. getaddrinfo() fails, the following might not set errno. // Make sure there is a consistent error message, not something random // which might even be "Error: Success". errno = EINVAL; return CZNC::Get().GetManager().ListenHost(m_uPort, "_LISTENER", - m_sBindHost, bSSL, SOMAXCONN, + m_sBindHost, IsSSL(), SOMAXCONN, m_pListener, 0, m_eAddr); } @@ -94,13 +89,21 @@ CUnixListener::~CUnixListener() { } bool CUnixListener::Listen() { - CString sName = "unix:" + m_sPath; + if (m_pListener) { + errno = EINVAL; + return false; + } m_pListener = new CRealListener(*this); - setupSSL(m_pListener); + SetupSSL(); - CZNC::Get().GetManager().AddSock(m_pListener, sName); - return m_pListener->ListenUnix(m_sPath); + if (m_pListener->ListenUnix(m_sPath)) { + CZNC::Get().GetManager().AddSock(m_pListener, "UNIX_LISTENER"); + return true; + } + + delete m_pListener; + return false; } CConfig CUnixListener::ToConfig() const { diff --git a/src/znc.cpp b/src/znc.cpp index 30cae265..8c233ff6 100644 --- a/src/znc.cpp +++ b/src/znc.cpp @@ -1620,8 +1620,37 @@ bool CZNC::AddListener(const CString& sLine, CString& sError) { sError); } +bool CZNC::CheckSslAndPemFile(bool bSSL, CString& sError) { +#ifndef HAVE_LIBSSL + if (bSSL) { + sError = t_s("SSL is not enabled"); + CUtils::PrintStatus(false, sError); + return false; + } +#else + CString sPemFile = GetPemLocation(); + + if (bSSL && !CFile::Exists(sPemFile)) { + sError = t_f("Unable to locate pem file: {1}")(sPemFile); + CUtils::PrintStatus(false, sError); + + // If stdin is e.g. /dev/null and we call GetBoolInput(), + // we are stuck in an endless loop! + if (isatty(0) && + CUtils::GetBoolInput("Would you like to create a new pem file?", + true)) { + sError.clear(); + WritePemFile(); + } else { + return false; + } + } +#endif + return true; +} + bool CZNC::AddTCPListener(unsigned short uPort, const CString& sBindHost, - const CString& sURIPrefixRaw, bool bSSL, EAddrType eAddr, + const CString& sURIPrefix, bool bSSL, EAddrType eAddr, CListener::EAcceptType eAccept, CString& sError) { CString sHostComment; @@ -1653,114 +1682,32 @@ bool CZNC::AddTCPListener(unsigned short uPort, const CString& sBindHost, } #endif -#ifndef HAVE_LIBSSL - if (bSSL) { - sError = t_s("SSL is not enabled"); - CUtils::PrintStatus(false, sError); - return false; - } -#else - CString sPemFile = GetPemLocation(); + if (!CheckSslAndPemFile(bSSL, sError)) return false; - if (bSSL && !CFile::Exists(sPemFile)) { - sError = t_f("Unable to locate pem file: {1}")(sPemFile); - CUtils::PrintStatus(false, sError); - - // If stdin is e.g. /dev/null and we call GetBoolInput(), - // we are stuck in an endless loop! - if (isatty(0) && - CUtils::GetBoolInput("Would you like to create a new pem file?", - true)) { - sError.clear(); - WritePemFile(); - } else { - return false; - } - - CUtils::PrintAction("Binding to port [+" + CString(uPort) + "]" + - sHostComment + sIPV6Comment); - } -#endif if (!uPort) { sError = t_s("Invalid port"); CUtils::PrintStatus(false, sError); return false; } - // URIPrefix must start with a slash and end without one. - CString sURIPrefix = CString(sURIPrefixRaw); - if (!sURIPrefix.empty()) { - if (!sURIPrefix.StartsWith("/")) { - sURIPrefix = "/" + sURIPrefix; - } - if (sURIPrefix.EndsWith("/")) { - sURIPrefix.TrimRight("/"); - } - } - CListener* pListener = new CTCPListener(uPort, sBindHost, sURIPrefix, bSSL, eAddr, eAccept); - - if (!pListener->Listen()) { - sError = FormatBindError(); - CUtils::PrintStatus(false, sError); - delete pListener; - return false; - } - - m_vpListeners.push_back(pListener); - CUtils::PrintStatus(true); - - return true; + return FinishAddingListener(pListener, sError); } -bool CZNC::AddUnixListener(const CString& sPath, const CString& sURIPrefixRaw, +bool CZNC::AddUnixListener(const CString& sPath, const CString& sURIPrefix, bool bSSL, CListener::EAcceptType eAccept, CString& sError) { - CUtils::PrintAction("Binding to path [" + sPath + "]"); + CUtils::PrintAction("Binding to path [" + sPath + "]" + (bSSL ? " with SSL" : "")); -#ifndef HAVE_LIBSSL - if (bSSL) { - sError = "SSL is not enabled"; - CUtils::PrintStatus(false, sError); - return false; - } -#else - CString sPemFile = GetPemLocation(); - - if (bSSL && !CFile::Exists(sPemFile)) { - sError = "Unable to locate pem file: [" + sPemFile + "]"; - CUtils::PrintStatus(false, sError); - - // If stdin is e.g. /dev/null and we call GetBoolInput(), - // we are stuck in an endless loop! - if (isatty(0) && - CUtils::GetBoolInput("Would you like to create a new pem file?", - true)) { - sError.clear(); - WritePemFile(); - } else { - return false; - } - - CUtils::PrintAction("Binding to path [" + sPath + "]"); - } -#endif - - // URIPrefix must start with a slash and end without one. - CString sURIPrefix = CString(sURIPrefixRaw); - if (!sURIPrefix.empty()) { - if (!sURIPrefix.StartsWith("/")) { - sURIPrefix = "/" + sURIPrefix; - } - if (sURIPrefix.EndsWith("/")) { - sURIPrefix.TrimRight("/"); - } - } + if (!CheckSslAndPemFile(bSSL, sError)) return false; CListener* pListener = new CUnixListener(sPath, sURIPrefix, bSSL, eAccept); + return FinishAddingListener(pListener, sError); +} +bool CZNC::FinishAddingListener(CListener* pListener, CString& sError) { if (!pListener->Listen()) { sError = FormatBindError(); CUtils::PrintStatus(false, sError); @@ -1817,6 +1764,16 @@ bool CZNC::AddListener(CConfig* pConfig, CString& sError) { return false; } + // URIPrefix must start with a slash and end without one. + if (!sURIPrefix.empty()) { + if (!sURIPrefix.StartsWith("/")) { + sURIPrefix = "/" + sURIPrefix; + } + if (sURIPrefix.EndsWith("/")) { + sURIPrefix.TrimRight("/"); + } + } + if (bTcpListener) { pConfig->FindStringEntry("host", sBindHost); pConfig->FindBoolEntry("ipv4", b4, true);