Add support to connect to server via unix socket

The syntax for AddServer command and config is chosen to be unix:/path or unix:ssl:/path

For security reasons, only admins can add such servers, to prevent users from poking around the file system.
This commit is contained in:
Alexey Sokolov
2025-04-20 22:20:52 +01:00
parent 66b17926cc
commit 63d10ccb17
10 changed files with 212 additions and 81 deletions
+38 -43
View File
@@ -215,8 +215,7 @@ void CIRCNetwork::Clone(const CIRCNetwork& Network, bool bCloneName) {
DelServers();
for (CServer* pServer : vServers) {
AddServer(pServer->GetName(), pServer->GetPort(), pServer->GetPass(),
pServer->IsSSL());
AddServer(*pServer);
}
m_uServerIdx = 0;
@@ -1155,6 +1154,11 @@ bool CIRCNetwork::DelServer(const CString& sName, unsigned short uPort,
return false;
}
CServer Server(sName, uPort, sPass);
return DelServer(Server);
}
bool CIRCNetwork::DelServer(const CServer& Server) {
unsigned int a = 0;
bool bSawCurrentServer = false;
CServer* pCurServer = GetCurrentServer();
@@ -1165,11 +1169,16 @@ bool CIRCNetwork::DelServer(const CString& sName, unsigned short uPort,
if (pServer == pCurServer) bSawCurrentServer = true;
if (!pServer->GetName().Equals(sName)) continue;
// Unix sockets can be removed with "unix:" prefix and without, both
// work - that's not part of GetName()
if (!pServer->GetName().Equals(Server.GetName())) continue;
if (uPort != 0 && pServer->GetPort() != uPort) continue;
// But it makes no sense to remove TCP server via "unix:hostname.com"
if (!pServer->IsUnixSocket() && Server.IsUnixSocket()) continue;
if (!sPass.empty() && pServer->GetPass() != sPass) continue;
if (Server.GetPort() != 6667 && pServer->GetPort() != Server.GetPort()) continue;
if (!Server.GetPass().empty() && pServer->GetPass() != Server.GetPass()) continue;
m_vServers.erase(it);
@@ -1205,21 +1214,23 @@ bool CIRCNetwork::AddServer(const CString& sName) {
return false;
}
bool bSSL = false;
CString sLine = sName;
sLine.Trim();
return AddServer(CServer::Parse(sName));
}
CString sHost = sLine.Token(0);
CString sPort = sLine.Token(1);
bool CIRCNetwork::AddServer(CServer Server) {
if (Server.GetName().empty()) return false;
#ifndef HAVE_LIBSSL
if (Server.IsSSL()) return false;
#endif
if (sPort.TrimPrefix("+")) {
bSSL = true;
// Check if server is already added
for (CServer* pServer : m_vServers) {
if (*pServer == Server) return false;
}
unsigned short uPort = sPort.ToUShort();
CString sPass = sLine.Token(2, true);
return AddServer(sHost, uPort, sPass, bSSL);
m_vServers.push_back(new CServer(std::move(Server)));
CheckIRCConnect();
return true;
}
bool CIRCNetwork::AddServer(const CString& sName, unsigned short uPort,
@@ -1234,30 +1245,7 @@ bool CIRCNetwork::AddServer(const CString& sName, unsigned short uPort,
return false;
}
if (!uPort) {
uPort = 6667;
}
// Check if server is already added
for (CServer* pServer : m_vServers) {
if (!sName.Equals(pServer->GetName())) continue;
if (uPort != pServer->GetPort()) continue;
if (sPass != pServer->GetPass()) continue;
if (bSSL != pServer->IsSSL()) continue;
// Server is already added
return false;
}
CServer* pServer = new CServer(sName, uPort, sPass, bSSL);
m_vServers.push_back(pServer);
CheckIRCConnect();
return true;
return AddServer(CServer(sName, uPort, sPass, bSSL));
}
CServer* CIRCNetwork::GetNextServer(bool bAdvance) {
@@ -1374,9 +1362,16 @@ bool CIRCNetwork::Connect() {
}
CString sSockName = "IRC::" + m_pUser->GetUsername() + "::" + m_sName;
CZNC::Get().GetManager().Connect(pServer->GetName(), pServer->GetPort(),
sSockName, 120, bSSL, GetBindHost(),
pIRCSock);
if (pServer->IsUnixSocket()) {
pIRCSock->SetSSL(bSSL);
CZNC::Get().GetManager().ConnectUnix(sSockName, pServer->GetName(),
pIRCSock);
} else {
CZNC::Get().GetManager().Connect(pServer->GetName(), pServer->GetPort(),
sSockName, 120, bSSL, GetBindHost(),
pIRCSock);
}
return true;
}