block_motd: Fix tracking of accepting motd from server

When the module is loaded globally or per-user the
`m_bTemporaryAcceptMotd` would be used to store state on connecting to
an MOTD which could lead to timing issues of a full or partial MOTD
being incorrectly sent to another server while another user requested
motd via the module.

This commit will now track this state per IRCSock so if another
connected user requests an MOTD and another server sends an MOTD it will
not lead to MOTDs being incorrectly unblocked.
This commit is contained in:
Kyle Fuller
2017-01-11 03:08:33 +00:00
parent aefc97d09a
commit 45a6329312
+33 -5
View File
@@ -15,6 +15,9 @@
*/
#include <znc/Modules.h>
#include <znc/IRCNetwork.h>
using std::set;
class CBlockMotd : public CModule {
public:
@@ -30,7 +33,12 @@ class CBlockMotd : public CModule {
~CBlockMotd() override {}
void OverrideCommand(const CString& sLine) {
m_bTemporaryAcceptMotd = true;
if (!GetNetwork() || !GetNetwork()->GetIRCSock()) {
PutModule("You are not connected to an IRC Server.");
return;
}
TemporarilyAcceptMotd();
const CString sServer = sLine.Token(1);
if (sServer.empty()) {
@@ -44,21 +52,41 @@ class CBlockMotd : public CModule {
const CString sCmd = sLine.Token(1);
if ((sCmd == "375" /* begin of MOTD */ || sCmd == "372" /* MOTD */) &&
!m_bTemporaryAcceptMotd)
!ShouldTemporarilyAcceptMotd())
return HALT;
if (sCmd == "376" /* End of MOTD */) {
if (!m_bTemporaryAcceptMotd) {
if (!ShouldTemporarilyAcceptMotd()) {
sLine = sLine.Token(0) + " 422 " + sLine.Token(2) +
" :MOTD blocked by ZNC";
}
m_bTemporaryAcceptMotd = false;
StopTemporarilyAcceptingMotd();
}
return CONTINUE;
}
void OnIRCDisconnected() override {
StopTemporarilyAcceptingMotd();
}
bool ShouldTemporarilyAcceptMotd() const {
return m_sTemporaryAcceptedMotdSocks.count(GetNetwork()->GetIRCSock()) > 0;
}
void TemporarilyAcceptMotd() {
if (ShouldTemporarilyAcceptMotd()) {
return;
}
m_sTemporaryAcceptedMotdSocks.insert(GetNetwork()->GetIRCSock());
}
void StopTemporarilyAcceptingMotd() {
m_sTemporaryAcceptedMotdSocks.erase(GetNetwork()->GetIRCSock());
}
private:
bool m_bTemporaryAcceptMotd = false;
set<CIRCSock *> m_sTemporaryAcceptedMotdSocks;
};
template <>