mirror of
https://github.com/znc/znc.git
synced 2026-08-08 01:43:03 +02:00
Add a way to disable certain capabilities
This is a way for admins to mitigate some issues caused by caps if such issues ever arise. E.g. add this to global level in znc.conf: DisableClientCap = sasl DisableServerCap = chghost DisableServerCap = message-tags Then these caps will be NAKed to client / not requested from server. Note that this mechanism doesn't fully prevent a cap from being activated, e.g. one could use *send_raw module to request it from server even when disabled.
This commit is contained in:
+12
-3
@@ -815,7 +815,8 @@ void CClient::RespondCap(const CString& sResponse) {
|
||||
PutClient(":irc.znc.in CAP " + GetNick() + " " + sResponse);
|
||||
}
|
||||
|
||||
static VCString MultiLine(const SCString& ssCaps) {
|
||||
template <typename ManyStrings>
|
||||
static VCString MultiLine(const ManyStrings& ssCaps) {
|
||||
VCString vsRes = {""};
|
||||
for (const CString& sCap : ssCaps) {
|
||||
if (vsRes.back().length() + sCap.length() > 400) {
|
||||
@@ -917,7 +918,15 @@ void CClient::HandleCap(const CMessage& Message) {
|
||||
}
|
||||
}
|
||||
NETWORKMODULECALL(OnClientCapLs(this, ssOfferCaps), GetUser(), GetNetwork(), this, NOTHING);
|
||||
VCString vsCaps = MultiLine(ssOfferCaps);
|
||||
VCString vsFilteredCaps;
|
||||
vsFilteredCaps.reserve(ssOfferCaps.size());
|
||||
for (CString sCap : std::move(ssOfferCaps)) {
|
||||
if (!CZNC::Get().GetClientCapBlacklist().count(
|
||||
sCap.Token(0, false, "="))) {
|
||||
vsFilteredCaps.push_back(std::move(sCap));
|
||||
}
|
||||
}
|
||||
VCString vsCaps = MultiLine(vsFilteredCaps);
|
||||
m_bInCap = true;
|
||||
if (HasCap302()) {
|
||||
m_bCapNotify = true;
|
||||
@@ -961,7 +970,7 @@ void CClient::HandleCap(const CMessage& Message) {
|
||||
NETWORKMODULECALL(IsClientCapSupported(this, sCap, bVal), GetUser(), GetNetwork(), this,
|
||||
&bAccepted);
|
||||
|
||||
if (!bAccepted) {
|
||||
if (!bAccepted || CZNC::Get().GetClientCapBlacklist().count(sCap)) {
|
||||
// Some unsupported capability is requested
|
||||
RespondCap("NAK :" + Message.GetParam(1));
|
||||
return;
|
||||
|
||||
@@ -416,6 +416,9 @@ bool CIRCSock::OnCapabilityMessage(CMessage& Message) {
|
||||
sCap = sToken.substr(0, eq);
|
||||
sValue = sToken.substr(eq + 1);
|
||||
}
|
||||
if (CZNC::Get().GetServerCapBlacklist().count(sCap)) {
|
||||
continue;
|
||||
}
|
||||
m_msCapLsValues[sCap] = sValue;
|
||||
if (OnServerCapAvailable(sCap, sValue) || mSupportedCaps.count(sCap)) {
|
||||
m_ssPendingCaps.insert(sCap);
|
||||
|
||||
+15
-1
@@ -55,11 +55,14 @@ CZNC::CZNC()
|
||||
m_vsBindHosts(),
|
||||
m_vsTrustedProxies(),
|
||||
m_vsMotd(),
|
||||
m_ssClientCapBlacklist(),
|
||||
m_ssServerCapBlacklist(),
|
||||
m_pLockFile(nullptr),
|
||||
m_uiConnectDelay(5),
|
||||
m_uiAnonIPLimit(10),
|
||||
m_uiMaxBufferSize(500),
|
||||
m_uDisabledSSLProtocols(Csock::EDP_SSL | Csock::EDP_TLSv1 | Csock::EDP_TLSv1_1),
|
||||
m_uDisabledSSLProtocols(Csock::EDP_SSL | Csock::EDP_TLSv1 |
|
||||
Csock::EDP_TLSv1_1),
|
||||
m_pModules(new CModules),
|
||||
m_uBytesRead(0),
|
||||
m_uBytesWritten(0),
|
||||
@@ -1185,6 +1188,17 @@ bool CZNC::LoadGlobal(CConfig& config, CString& sError) {
|
||||
AddTrustedProxy(sProxy);
|
||||
}
|
||||
|
||||
m_ssClientCapBlacklist.clear();
|
||||
config.FindStringVector("disableclientcap", vsList);
|
||||
for (const CString& sCap : vsList) {
|
||||
m_ssClientCapBlacklist.insert(sCap);
|
||||
}
|
||||
m_ssServerCapBlacklist.clear();
|
||||
config.FindStringVector("disableservercap", vsList);
|
||||
for (const CString& sCap : vsList) {
|
||||
m_ssServerCapBlacklist.insert(sCap);
|
||||
}
|
||||
|
||||
CString sVal;
|
||||
if (config.FindStringEntry("pidfile", sVal)) m_sPidFile = sVal;
|
||||
if (config.FindStringEntry("statusprefix", sVal)) m_sStatusPrefix = sVal;
|
||||
|
||||
Reference in New Issue
Block a user