mirror of
https://github.com/znc/znc.git
synced 2026-08-07 01:13:25 +02:00
Add support for listening on a unix domain socket
So far this is not integrated with ClientCommand.cpp or webadmin.cpp, so the only way to actually use this is to hand-editing the config with a <Listener> section like the following: <Listener 42> Path = /tmp/listen SSL = false </Listener> So far this received only very basic testing. I did not even test SSL support. Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
@@ -92,6 +92,28 @@ class CTCPListener : public CListener {
|
||||
CString m_sBindHost;
|
||||
};
|
||||
|
||||
class CUnixListener : public CListener {
|
||||
public:
|
||||
CUnixListener(const CString& sPath, const CString& sURIPrefix, bool bSSL,
|
||||
EAcceptType eAccept)
|
||||
: CListener(sURIPrefix, bSSL, eAccept),
|
||||
m_sPath(sPath) {}
|
||||
~CUnixListener();
|
||||
|
||||
CUnixListener(const CUnixListener&) = delete;
|
||||
CUnixListener& operator=(const CUnixListener&) = delete;
|
||||
|
||||
// Getters
|
||||
const CString& GetPath() const { return m_sPath; }
|
||||
// !Getters
|
||||
|
||||
bool Listen() override;
|
||||
CConfig ToConfig() const override;
|
||||
|
||||
protected:
|
||||
CString m_sPath;
|
||||
};
|
||||
|
||||
class CRealListener : public CZNCSock {
|
||||
public:
|
||||
CRealListener(CListener& listener) : CZNCSock(), m_Listener(listener) {}
|
||||
|
||||
@@ -204,6 +204,8 @@ class CZNC {
|
||||
bool AddListener(unsigned short uPort, const CString& sBindHost,
|
||||
const CString& sURIPrefix, bool bSSL, EAddrType eAddr,
|
||||
CListener::EAcceptType eAccept, CString& sError);
|
||||
bool AddListener(const CString& sPath, const CString& sURIPrefix, bool bSSL,
|
||||
CListener::EAcceptType eAccept, CString& sError);
|
||||
bool DelListener(CListener*);
|
||||
|
||||
// Message of the Day
|
||||
|
||||
@@ -83,6 +83,35 @@ CConfig CTCPListener::ToConfig() const {
|
||||
return listenerConfig;
|
||||
}
|
||||
|
||||
CUnixListener::~CUnixListener() {
|
||||
}
|
||||
|
||||
bool CUnixListener::Listen() {
|
||||
CString sName = "unix:" + m_sPath;
|
||||
|
||||
m_pListener = new CRealListener(*this);
|
||||
|
||||
#ifdef HAVE_LIBSSL
|
||||
if (IsSSL()) {
|
||||
m_pListener->SetSSL(true);
|
||||
m_pListener->SetPemLocation(CZNC::Get().GetPemLocation());
|
||||
m_pListener->SetKeyLocation(CZNC::Get().GetKeyLocation());
|
||||
m_pListener->SetDHParamLocation(CZNC::Get().GetDHParamLocation());
|
||||
}
|
||||
#endif
|
||||
|
||||
CZNC::Get().GetManager().AddSock(m_pListener, sName);
|
||||
return m_pListener->ListenUnix(m_sPath);
|
||||
}
|
||||
|
||||
CConfig CUnixListener::ToConfig() const {
|
||||
CConfig listenerConfig = CListener::ToConfig();
|
||||
|
||||
listenerConfig.AddKeyValuePair("Path", GetPath());
|
||||
|
||||
return listenerConfig;
|
||||
}
|
||||
|
||||
void CListener::ResetRealListener() { m_pListener = nullptr; }
|
||||
|
||||
CRealListener::~CRealListener() { m_Listener.ResetRealListener(); }
|
||||
|
||||
+92
-21
@@ -1717,9 +1717,70 @@ bool CZNC::AddListener(unsigned short uPort, const CString& sBindHost,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CZNC::AddListener(const CString& sPath, const CString& sURIPrefixRaw,
|
||||
bool bSSL, CListener::EAcceptType eAccept,
|
||||
CString& sError) {
|
||||
CUtils::PrintAction("Binding to path [" + sPath + "]");
|
||||
|
||||
#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("/");
|
||||
}
|
||||
}
|
||||
|
||||
CListener* pListener =
|
||||
new CUnixListener(sPath, sURIPrefix, bSSL, eAccept);
|
||||
|
||||
if (!pListener->Listen()) {
|
||||
sError = FormatBindError();
|
||||
CUtils::PrintStatus(false, sError);
|
||||
delete pListener;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_vpListeners.push_back(pListener);
|
||||
CUtils::PrintStatus(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CZNC::AddListener(CConfig* pConfig, CString& sError) {
|
||||
CString sBindHost;
|
||||
CString sURIPrefix;
|
||||
CString sPath;
|
||||
bool bSSL;
|
||||
bool b4;
|
||||
#ifdef HAVE_IPV6
|
||||
@@ -1730,32 +1791,22 @@ bool CZNC::AddListener(CConfig* pConfig, CString& sError) {
|
||||
bool bIRC;
|
||||
bool bWeb;
|
||||
unsigned short uPort;
|
||||
bool bTcpListener = true;
|
||||
|
||||
if (!pConfig->FindUShortEntry("port", uPort)) {
|
||||
sError = "No port given";
|
||||
CUtils::PrintError(sError);
|
||||
return false;
|
||||
bTcpListener = false;
|
||||
if (!pConfig->FindStringEntry("path", sPath)) {
|
||||
sError = "No port and no path given";
|
||||
CUtils::PrintError(sError);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
pConfig->FindStringEntry("host", sBindHost);
|
||||
|
||||
pConfig->FindBoolEntry("ssl", bSSL, false);
|
||||
pConfig->FindBoolEntry("ipv4", b4, true);
|
||||
pConfig->FindBoolEntry("ipv6", b6, b6);
|
||||
pConfig->FindBoolEntry("allowirc", bIRC, true);
|
||||
pConfig->FindBoolEntry("allowweb", bWeb, true);
|
||||
pConfig->FindStringEntry("uriprefix", sURIPrefix);
|
||||
|
||||
EAddrType eAddr;
|
||||
if (b4 && b6) {
|
||||
eAddr = ADDR_ALL;
|
||||
} else if (b4 && !b6) {
|
||||
eAddr = ADDR_IPV4ONLY;
|
||||
} else if (!b4 && b6) {
|
||||
eAddr = ADDR_IPV6ONLY;
|
||||
} else {
|
||||
sError = "No address family given";
|
||||
CUtils::PrintError(sError);
|
||||
return false;
|
||||
}
|
||||
|
||||
CListener::EAcceptType eAccept;
|
||||
if (bIRC && bWeb) {
|
||||
eAccept = CListener::ACCEPT_ALL;
|
||||
@@ -1769,8 +1820,28 @@ bool CZNC::AddListener(CConfig* pConfig, CString& sError) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return AddListener(uPort, sBindHost, sURIPrefix, bSSL, eAddr, eAccept,
|
||||
sError);
|
||||
if (bTcpListener) {
|
||||
pConfig->FindStringEntry("host", sBindHost);
|
||||
pConfig->FindBoolEntry("ipv4", b4, true);
|
||||
pConfig->FindBoolEntry("ipv6", b6, b6);
|
||||
|
||||
EAddrType eAddr;
|
||||
if (b4 && b6) {
|
||||
eAddr = ADDR_ALL;
|
||||
} else if (b4 && !b6) {
|
||||
eAddr = ADDR_IPV4ONLY;
|
||||
} else if (!b4 && b6) {
|
||||
eAddr = ADDR_IPV6ONLY;
|
||||
} else {
|
||||
sError = "No address family given";
|
||||
CUtils::PrintError(sError);
|
||||
return false;
|
||||
}
|
||||
|
||||
return AddListener(uPort, sBindHost, sURIPrefix, bSSL, eAddr, eAccept,
|
||||
sError);
|
||||
}
|
||||
return AddListener(sPath, sURIPrefix, bSSL, eAccept, sError);
|
||||
}
|
||||
|
||||
bool CZNC::AddListener(CListener* pListener) {
|
||||
|
||||
Reference in New Issue
Block a user