mirror of
https://github.com/znc/znc.git
synced 2026-05-08 22:34:45 +02:00
Send a MODE request when JOINing
This kind of reverts/fixes f1cb09bd9c.
Robby found a bug with evil ChanServ which goes like this:
- You join an empty, but registered channel and the IRCd applies its default
modes (+nt), but ZNC didn't ask for MODE, so doesn't know this.
- ChanServ applies whatever channel modes it wants to apply. This causes ZNC to
see a mode change (e.g. +s).
The result of this is that ZNC thinks that the channel has mode +s and it will
tell every client that connects to it about this.
The fix is to send a MODE request when JOINing. To make sure that we don't
confuse clients, we block the reply.
Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
@@ -54,6 +54,7 @@ CChan::~CChan() {
|
||||
|
||||
void CChan::Reset() {
|
||||
m_bIsOn = false;
|
||||
m_bModeKnown = false;
|
||||
m_musModes.clear();
|
||||
m_sTopic = "";
|
||||
m_sTopicOwner = "";
|
||||
|
||||
@@ -100,6 +100,7 @@ public:
|
||||
// !wrappers
|
||||
|
||||
// Setters
|
||||
void SetModeKnown(bool b) { m_bModeKnown = b; }
|
||||
void SetIsOn(bool b) { m_bIsOn = b; if (!b) { Reset(); } }
|
||||
void SetKey(const CString& s) { m_sKey = s; }
|
||||
void SetTopic(const CString& s) { m_sTopic = s; }
|
||||
@@ -118,6 +119,7 @@ public:
|
||||
// !Setters
|
||||
|
||||
// Getters
|
||||
bool IsModeKnown() const { return m_bModeKnown; }
|
||||
bool HasMode(unsigned char uMode) const;
|
||||
CString GetOptions() const;
|
||||
CString GetModeArg(unsigned char uMode) const;
|
||||
@@ -162,6 +164,7 @@ protected:
|
||||
unsigned int m_uBufferCount;
|
||||
vector<CString> m_vsBuffer;
|
||||
|
||||
bool m_bModeKnown;
|
||||
map<unsigned char, CString> m_musModes;
|
||||
};
|
||||
|
||||
|
||||
+18
@@ -196,6 +196,15 @@ void CIRCSock::ReadLine(const CString& sData) {
|
||||
|
||||
if (pChan) {
|
||||
pChan->SetModes(sRest.Token(1, true));
|
||||
|
||||
// We don't SetModeKnown(true) here,
|
||||
// because a 329 will follow
|
||||
if (!pChan->IsModeKnown()) {
|
||||
// When we JOIN, we send a MODE
|
||||
// request. This makes sure the
|
||||
// reply isn't forwarded.
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -206,6 +215,14 @@ void CIRCSock::ReadLine(const CString& sData) {
|
||||
if (pChan) {
|
||||
unsigned long ulDate = sLine.Token(4).ToULong();
|
||||
pChan->SetCreationDate(ulDate);
|
||||
|
||||
if (!pChan->IsModeKnown()) {
|
||||
pChan->SetModeKnown(true);
|
||||
// When we JOIN, we send a MODE
|
||||
// request. This makes sure the
|
||||
// reply isn't forwarded.
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -455,6 +472,7 @@ void CIRCSock::ReadLine(const CString& sData) {
|
||||
pChan->ResetJoinTries();
|
||||
pChan->Enable();
|
||||
pChan->SetIsOn(true);
|
||||
PutIRC("MODE " + sChan);
|
||||
}
|
||||
} else {
|
||||
pChan = m_pUser->FindChan(sChan);
|
||||
|
||||
Reference in New Issue
Block a user