summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorw00t <w00t@e03df62e-2008-0410-955e-edbf42e46eb7>2008-10-27 22:29:56 +0000
committerw00t <w00t@e03df62e-2008-0410-955e-edbf42e46eb7>2008-10-27 22:29:56 +0000
commit1a738eb97eb7ac62b7d28bd40b03969d175ee6e3 (patch)
treef9aba6c851c7c3575d10b23caaf8db79af159f23
parent50234923b292122bb19296952b947d55b1760c62 (diff)
Add user/channel mode synchronisation detection to CAPAB - link will now drop if modes differ in some way (one side requires param, other doesn't, etc). Same for user modes.
This will not affect services. Side effect: Modes::ChanModes() -> Modes::GiveModeList(ModeMasks), mode list is formatted identically for both MASK_CHANNEL and MASK_USER. git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@10733 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r--include/mode.h9
-rw-r--r--src/mode.cpp4
-rw-r--r--src/modules/m_spanningtree/capab.cpp12
-rw-r--r--src/server.cpp2
4 files changed, 21 insertions, 6 deletions
diff --git a/include/mode.h b/include/mode.h
index 894e7bef2..a8dd839dd 100644
--- a/include/mode.h
+++ b/include/mode.h
@@ -544,9 +544,14 @@ class CoreExport ModeParser : public classbase
*/
std::string ParaModeList();
- /** Generates the CHANMODES= 005 sequence
+ /** Generates a list of modes, comma seperated by type:
+ * 1; Listmodes EXCEPT those with a prefix
+ * 2; Modes that take a param when adding or removing
+ * 3; Modes that only take a param when adding
+ * 4; Modes that dont take a param
*/
- std::string ChanModes();
+ std::string GiveModeList(ModeMasks m);
+
/** Used by this class internally during std::sort and 005 generation
*/
static bool PrefixComparison(prefixtype one, prefixtype two);
diff --git a/src/mode.cpp b/src/mode.cpp
index bdec78737..a5549a964 100644
--- a/src/mode.cpp
+++ b/src/mode.cpp
@@ -1010,7 +1010,7 @@ std::string ModeParser::ModeString(User* user, Channel* channel, bool nick_suffi
return types;
}
-std::string ModeParser::ChanModes()
+std::string ModeParser::GiveModeList(ModeMasks m)
{
std::string type1; /* Listmodes EXCEPT those with a prefix */
std::string type2; /* Modes that take a param when adding or removing */
@@ -1022,7 +1022,7 @@ std::string ModeParser::ChanModes()
if ((!ServerInstance->Config->AllowHalfop) && (mode == 'h'))
continue;
- unsigned char pos = (mode-65) | MASK_CHANNEL;
+ unsigned char pos = (mode-65) | m;
/* One parameter when adding */
if (modehandlers[pos])
{
diff --git a/src/modules/m_spanningtree/capab.cpp b/src/modules/m_spanningtree/capab.cpp
index 8b02b9545..e8fe75177 100644
--- a/src/modules/m_spanningtree/capab.cpp
+++ b/src/modules/m_spanningtree/capab.cpp
@@ -95,7 +95,8 @@ void TreeSocket::SendCapabilities()
" IP6SUPPORT="+ConvToStr(ip6support)+
" PROTOCOL="+ConvToStr(ProtocolVersion)+extra+
" PREFIX="+ServerInstance->Modes->BuildPrefixes()+
- " CHANMODES="+ServerInstance->Modes->ChanModes()+
+ " CHANMODES="+ServerInstance->Modes->GiveModeList(MASK_CHANNEL)+
+ " USERMODES="+ServerInstance->Modes->GiveModeList(MASK_USER)+
" SVSPART=1");
this->WriteLine("CAPAB END");
@@ -186,9 +187,18 @@ bool TreeSocket::Capab(const std::deque<std::string> &params)
if(this->CapKeys.find("PREFIX") != this->CapKeys.end() && this->CapKeys.find("PREFIX")->second != this->ServerInstance->Modes->BuildPrefixes())
reason = "One or more of the prefixes on the remote server are invalid on this server.";
+ if(this->CapKeys.find("CHANMODES") != this->CapKeys.end() && this->CapKeys.find("CHANMODES")->second != this->ServerInstance->Modes->GiveModeList(MASK_CHANNEL))
+ reason = "One or more of the channel modes on the remote server are invalid on this server.";
+
+ if(this->CapKeys.find("USERMODES") != this->CapKeys.end() && this->CapKeys.find("USERMODES")->second != this->ServerInstance->Modes->GiveModeList(MASK_USER))
+ reason = "One or more of the user modes on the remote server are invalid on this server.";
+
+
if (((this->CapKeys.find("HALFOP") == this->CapKeys.end()) && (ServerInstance->Config->AllowHalfop)) || ((this->CapKeys.find("HALFOP") != this->CapKeys.end()) && (this->CapKeys.find("HALFOP")->second != ConvToStr(ServerInstance->Config->AllowHalfop))))
reason = "We don't both have halfop support enabled/disabled identically";
+
+
/* Challenge response, store their challenge for our password */
std::map<std::string,std::string>::iterator n = this->CapKeys.find("CHALLENGE");
if (Utils->ChallengeResponse && (n != this->CapKeys.end()) && (ServerInstance->Modules->Find("m_sha256.so")))
diff --git a/src/server.cpp b/src/server.cpp
index 8879e1eb8..c3efc7e6b 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -86,7 +86,7 @@ void InspIRCd::BuildISupport()
std::stringstream v;
v << "WALLCHOPS WALLVOICES MODES=" << Config->Limits.MaxModes << " CHANTYPES=# PREFIX=" << this->Modes->BuildPrefixes() << " MAP MAXCHANNELS=" << Config->MaxChans << " MAXBANS=60 VBANLIST NICKLEN=" << Config->Limits.NickMax;
v << " CASEMAPPING=rfc1459 STATUSMSG=@" << (this->Config->AllowHalfop ? "%" : "") << "+ CHARSET=ascii TOPICLEN=" << Config->Limits.MaxTopic << " KICKLEN=" << Config->Limits.MaxKick << " MAXTARGETS=" << Config->MaxTargets;
- v << " AWAYLEN=" << Config->Limits.MaxAway << " CHANMODES=" << this->Modes->ChanModes() << " FNC NETWORK=" << Config->Network << " MAXPARA=32 ELIST=MU";
+ v << " AWAYLEN=" << Config->Limits.MaxAway << " CHANMODES=" << this->Modes->GiveModeList(MASK_CHANNEL) << " FNC NETWORK=" << Config->Network << " MAXPARA=32 ELIST=MU";
Config->data005 = v.str();
FOREACH_MOD_I(this,I_On005Numeric,On005Numeric(Config->data005));
Config->Update005();