summaryrefslogtreecommitdiff
path: root/modules/protocol/inspircd20.cpp
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2012-10-01 01:56:57 -0400
committerAdam <Adam@anope.org>2012-10-01 01:56:57 -0400
commit89428a9d1032e3c2a6e397629a32862b3e58d708 (patch)
treed507904b3fa1cc084f0f3e688c839bcdd47f79d7 /modules/protocol/inspircd20.cpp
parentb937d6310d9a7c0e2434200306b63d513cb2ae61 (diff)
Cleanup of all of the protocol modules, rewrote message handling system to be a bit more C++ ish
Diffstat (limited to 'modules/protocol/inspircd20.cpp')
-rw-r--r--modules/protocol/inspircd20.cpp399
1 files changed, 96 insertions, 303 deletions
diff --git a/modules/protocol/inspircd20.cpp b/modules/protocol/inspircd20.cpp
index b1352959c..25d0c9333 100644
--- a/modules/protocol/inspircd20.cpp
+++ b/modules/protocol/inspircd20.cpp
@@ -20,255 +20,23 @@ static bool has_globopsmod = true; // Not a typo
static bool has_rlinemod = false;
#include "inspircd-ts6.h"
-IRCDVar myIrcd = {
- "InspIRCd 2.0", /* ircd name */
- "+I", /* Modes used by pseudoclients */
- 1, /* SVSNICK */
- 1, /* Vhost */
- 0, /* Supports SNlines */
- 1, /* Supports SQlines */
- 1, /* Supports SZlines */
- 0, /* Join 2 Message */
- 0, /* Chan SQlines */
- 0, /* Quit on Kill */
- 1, /* vidents */
- 1, /* svshold */
- 0, /* time stamp on mode */
- 0, /* O:LINE */
- 1, /* UMODE */
- 1, /* No Knock requires +i */
- 0, /* Can remove User Channel Modes with SVSMODE */
- 0, /* Sglines are not enforced until user reconnects */
- 1, /* ts6 */
- "$", /* TLD Prefix for Global */
- 20, /* Max number of modes we can send per line */
- 1, /* IRCd sends a SSL users certificate fingerprint */
-};
-
static bool has_servicesmod = false;
static bool has_svsholdmod = false;
-class InspIRCdProto : public InspIRCdTS6Proto
+class InspIRCd20Proto : public InspIRCdTS6Proto
{
+ public:
+ InspIRCd20Proto() : InspIRCdTS6Proto("InspIRCd 2.0") { }
+
void SendConnect() anope_override
{
UplinkSocket::Message() << "CAPAB START 1202";
UplinkSocket::Message() << "CAPAB CAPABILITIES :PROTOCOL=1202";
UplinkSocket::Message() << "CAPAB END";
- SendServer(Me);
- UplinkSocket::Message(Me) << "BURST";
- Module *enc = ModuleManager::FindFirstOf(ENCRYPTION);
- UplinkSocket::Message(Me) << "VERSION :Anope-" << Anope::Version() << " " << Me->GetName() << " :" << ircd->name <<" - (" << (enc ? enc->name : "unknown") << ") -- " << Anope::VersionBuildString();
+ InspIRCdTS6Proto::SendConnect();
}
};
-bool event_ftopic(const Anope::string &source, const std::vector<Anope::string> &params)
-{
- /* :source FTOPIC channel ts setby :topic */
- if (params.size() < 4)
- return true;
-
- Channel *c = findchan(params[0]);
- if (!c)
- {
- Log(LOG_DEBUG) << "TOPIC " << params[3] << " for nonexistent channel " << params[0];
- return true;
- }
-
- c->ChangeTopicInternal(params[2], params[3], Anope::string(params[1]).is_pos_number_only() ? convertTo<time_t>(params[1]) : Anope::CurTime);
-
- return true;
-}
-
-bool event_opertype(const Anope::string &source, const std::vector<Anope::string> &params)
-{
- /* opertype is equivalent to mode +o because servers
- dont do this directly */
- User *u = finduser(source);
- if (u && !u->HasMode(UMODE_OPER))
- {
- std::vector<Anope::string> newparams;
- newparams.push_back(source);
- newparams.push_back("+o");
- return ircdmessage->OnMode(source, newparams);
- }
- return true;
-}
-
-bool event_fmode(const Anope::string &source, const std::vector<Anope::string> &params)
-{
- /* :source FMODE #test 12345678 +nto foo */
- if (params.size() < 3)
- return true;
-
- Channel *c = findchan(params[0]);
- if (!c)
- return true;
-
- /* Checking the TS for validity to avoid desyncs */
- time_t ts = Anope::string(params[1]).is_pos_number_only() ? convertTo<time_t>(params[1]) : 0;
- if (c->creation_time > ts)
- {
- /* Our TS is bigger, we should lower it */
- c->creation_time = ts;
- c->Reset();
- }
- else if (c->creation_time < ts)
- /* The TS we got is bigger, we should ignore this message. */
- return true;
-
- /* TS's are equal now, so we can proceed with parsing */
- std::vector<Anope::string> newparams;
- newparams.push_back(params[0]);
- newparams.push_back(params[1]);
- Anope::string modes = params[2];
- for (unsigned n = 3; n < params.size(); ++n)
- modes += " " + params[n];
- newparams.push_back(modes);
-
- return ircdmessage->OnMode(source, newparams);
-}
-
-bool event_chgname(const Anope::string &source, const std::vector<Anope::string> &params)
-{
- User *u = finduser(source);
-
- if (!u)
- {
- Log(LOG_DEBUG) << "FNAME for nonexistent user " << source;
- return true;
- }
- else if (params.empty())
- return true;
-
- u->SetRealname(params[0]);
- return true;
-}
-
-bool event_chgident(const Anope::string &source, const std::vector<Anope::string> &params)
-{
- User *u = finduser(source);
-
- if (!u)
- {
- Log(LOG_DEBUG) << "FIDENT for nonexistent user " << source;
- return true;
- }
-
- u->SetIdent(params[0]);
- return true;
-}
-
-bool event_chghost(const Anope::string &source, const std::vector<Anope::string> &params)
-{
- User *u = finduser(source);
-
- if (!u)
- {
- Log(LOG_DEBUG) << "FHOST for nonexistent user " << source;
- return true;
- }
-
- u->SetDisplayedHost(params[0]);
- return true;
-}
-
-
-/*
- * source = numeric of the sending server
- * params[0] = uuid
- * params[1] = metadata name
- * params[2] = data
- */
-bool event_metadata(const Anope::string &source, const std::vector<Anope::string> &params)
-{
- if (params.size() < 3)
- return true;
- else if (params[1].equals_cs("accountname"))
- {
- User *u = finduser(params[0]);
- NickCore *nc = findcore(params[2]);
- if (u && nc)
- {
- u->Login(nc);
-
- const NickAlias *user_na = findnick(u->nick);
- if (!Config->NoNicknameOwnership && nickserv && user_na && user_na->nc == nc && user_na->nc->HasFlag(NI_UNCONFIRMED) == false)
- u->SetMode(findbot(Config->NickServ), UMODE_REGISTERED);
- }
- }
-
- /*
- * possible incoming ssl_cert messages:
- * Received: :409 METADATA 409AAAAAA ssl_cert :vTrSe c38070ce96e41cc144ed6590a68d45a6 <...> <...>
- * Received: :409 METADATA 409AAAAAC ssl_cert :vTrSE Could not get peer certificate: error:00000000:lib(0):func(0):reason(0)
- */
- else if (params[1].equals_cs("ssl_cert"))
- {
- User *u = finduser(params[0]);
- if (!u)
- return true;
- std::string data = params[2].c_str();
- size_t pos1 = data.find(' ') + 1;
- size_t pos2 = data.find(' ', pos1);
- if ((pos2 - pos1) >= 32) // inspircd supports md5 and sha1 fingerprint hashes -> size 32 or 40 bytes.
- {
- u->fingerprint = data.substr(pos1, pos2 - pos1);
- FOREACH_MOD(I_OnFingerprint, OnFingerprint(u));
- }
- }
- return true;
-}
-
-bool event_encap(const Anope::string &source, const std::vector<Anope::string> &params)
-{
- if (params.size() < 2 || Server::Find(params[0]) != Me)
- return true;
-
- if (params[1] == "CHGIDENT" && params.size() > 3)
- {
- User *u = finduser(params[2]);
- if (!u || u->server != Me)
- return true;
-
- u->SetIdent(params[3]);
- UplinkSocket::Message(u) << "FIDENT " << params[3];
- }
- else if (params[1] == "CHGHOST" && params.size() > 3)
- {
- User *u = finduser(params[2]);
- if (!u || u->server != Me)
- return true;
-
- u->SetDisplayedHost(params[3]);
- UplinkSocket::Message(u) << "FHOST " << params[3];
- }
- else if (params[1] == "CHGNAME" && params.size() > 3)
- {
- User *u = finduser(params[2]);
- if (!u || u->server != Me)
- return true;
-
- u->SetRealname(params[3]);
- UplinkSocket::Message(u) << "FNAME " << params[3];
- }
-
- return true;
-}
-
-bool event_endburst(const Anope::string &source, const std::vector<Anope::string> &params)
-{
- Server *s = Server::Find(source);
-
- if (!s)
- throw CoreException("Got ENDBURST without a source");
-
- Log(LOG_DEBUG) << "Processed ENDBURST for " << s->GetName();
-
- s->Sync(true);
- return true;
-}
-
class InspIRCdExtBan : public ChannelModeList
{
public:
@@ -342,37 +110,11 @@ class InspIRCdExtBan : public ChannelModeList
}
};
-class Inspircd20IRCdMessage : public InspircdIRCdMessage
+struct IRCDMessageCapab : IRCDMessage
{
- public:
- /*
- * [Nov 03 22:09:58.176252 2009] debug: Received: :964 UID 964AAAAAC 1225746297 w00t2 localhost testnet.user w00t 127.0.0.1 1225746302 +iosw +ACGJKLNOQcdfgjklnoqtx :Robin Burchell <w00t@inspircd.org>
- * 0: uid
- * 1: ts
- * 2: nick
- * 3: host
- * 4: dhost
- * 5: ident
- * 6: ip
- * 7: signon
- * 8+: modes and params -- IMPORTANT, some modes (e.g. +s) may have parameters. So don't assume a fixed position of realname!
- * last: realname
- */
- bool OnUID(const Anope::string &source, const std::vector<Anope::string> &params) anope_override
- {
- time_t ts = Anope::string(params[1]).is_pos_number_only() ? convertTo<time_t>(params[1]) : 0;
+ IRCDMessageCapab() : IRCDMessage("CAPAB", 1) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
- Anope::string modes = params[8];
- for (unsigned i = 9; i < params.size() - 1; ++i)
- modes += Anope::string(" ") + params[i];
- User *user = do_nick("", params[2], params[5], params[3], source, params[params.size() - 1], ts, params[6], params[4], params[0], modes);
- if (user && user->server->IsSynced() && nickserv)
- nickserv->Validate(user);
-
- return true;
- }
-
- bool OnCapab(const Anope::string &source, const std::vector<Anope::string> &params) anope_override
+ bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
{
if (params[0].equals_cs("START"))
{
@@ -390,7 +132,7 @@ class Inspircd20IRCdMessage : public InspircdIRCdMessage
has_chghostmod = false;
has_chgidentmod = false;
}
- else if (params[0].equals_cs("CHANMODES"))
+ else if (params[0].equals_cs("CHANMODES") && params.size() > 1)
{
spacesepstream ssep(params[1]);
Anope::string capab;
@@ -490,7 +232,7 @@ class Inspircd20IRCdMessage : public InspircdIRCdMessage
Log() << "Unrecognized mode string in CAPAB CHANMODES: " << capab;
}
}
- if (params[0].equals_cs("USERMODES"))
+ if (params[0].equals_cs("USERMODES") && params.size() > 1)
{
spacesepstream ssep(params[1]);
Anope::string capab;
@@ -528,7 +270,7 @@ class Inspircd20IRCdMessage : public InspircdIRCdMessage
else if (modename.equals_cs("servprotect"))
{
um = new UserMode(UMODE_PROTECTED, modechar[0]);
- ircd->pseudoclient_mode = "+Ik"; // XXX
+ ircdproto->DefaultPseudoclientModes += "k";
}
else if (modename.equals_cs("showwhois"))
um = new UserMode(UMODE_WHOIS, modechar[0]);
@@ -547,7 +289,7 @@ class Inspircd20IRCdMessage : public InspircdIRCdMessage
Log() << "Unrecognized mode string in CAPAB USERMODES: " << capab;
}
}
- else if (params[0].equals_cs("MODULES"))
+ else if (params[0].equals_cs("MODULES") && params.size() > 1)
{
spacesepstream ssep(params[1]);
Anope::string module;
@@ -559,12 +301,12 @@ class Inspircd20IRCdMessage : public InspircdIRCdMessage
else if (module.find("m_rline.so") == 0)
{
has_rlinemod = true;
- if (!Config->RegexEngine.empty() && Config->RegexEngine != module.substr(11))
+ if (!Config->RegexEngine.empty() && module.length() > 11 && Config->RegexEngine != module.substr(11))
Log() << "Warning: InspIRCd is using regex engine " << module.substr(11) << ", but we have " << Config->RegexEngine << ". This may cause inconsistencies.";
}
}
}
- else if (params[0].equals_cs("MODSUPPORT"))
+ else if (params[0].equals_cs("MODSUPPORT") && params.size() > 1)
{
spacesepstream ssep(params[1]);
Anope::string module;
@@ -579,7 +321,7 @@ class Inspircd20IRCdMessage : public InspircdIRCdMessage
has_chgidentmod = true;
}
}
- else if (params[0].equals_cs("CAPABILITIES"))
+ else if (params[0].equals_cs("CAPABILITIES") && params.size() > 1)
{
spacesepstream ssep(params[1]);
Anope::string capab;
@@ -643,7 +385,7 @@ class Inspircd20IRCdMessage : public InspircdIRCdMessage
else if (capab.find("MAXMODES=") != Anope::string::npos)
{
Anope::string maxmodes(capab.begin() + 9, capab.end());
- ircd->maxmodes = maxmodes.is_pos_number_only() ? convertTo<unsigned>(maxmodes) : 3;
+ ircdproto->MaxModes = maxmodes.is_pos_number_only() ? convertTo<unsigned>(maxmodes) : 3;
}
else if (capab.find("PREFIX=") != Anope::string::npos)
{
@@ -688,10 +430,49 @@ class Inspircd20IRCdMessage : public InspircdIRCdMessage
Log() << "CHGHOST missing, Usage disabled until module is loaded.";
if (!has_chgidentmod)
Log() << "CHGIDENT missing, Usage disabled until module is loaded.";
- ircd->svshold = has_svsholdmod;
+ ircdproto->CanSVSHold = has_svsholdmod;
}
- IRCdMessage::OnCapab(source, params);
+ return true;
+ }
+};
+
+struct IRCDMessageEncap : IRCDMessage
+{
+ IRCDMessageEncap() : IRCDMessage("ENCAP", 4) { }
+
+ bool Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
+ {
+ if (Anope::Match(Me->GetSID(), params[0]) == false)
+ return true;
+
+ if (params[1] == "CHGIDENT")
+ {
+ User *u = finduser(params[2]);
+ if (!u || u->server != Me)
+ return true;
+
+ u->SetIdent(params[3]);
+ UplinkSocket::Message(u) << "FIDENT " << params[3];
+ }
+ else if (params[1] == "CHGHOST")
+ {
+ User *u = finduser(params[2]);
+ if (!u || u->server != Me)
+ return true;
+
+ u->SetDisplayedHost(params[3]);
+ UplinkSocket::Message(u) << "FHOST " << params[3];
+ }
+ else if (params[1] == "CHGNAME")
+ {
+ User *u = finduser(params[2]);
+ if (!u || u->server != Me)
+ return true;
+
+ u->SetRealname(params[3]);
+ UplinkSocket::Message(u) << "FNAME " << params[3];
+ }
return true;
}
@@ -699,31 +480,50 @@ class Inspircd20IRCdMessage : public InspircdIRCdMessage
class ProtoInspIRCd : public Module
{
- Message message_endburst, message_time,
- message_rsquit, message_svsmode, message_fhost,
- message_chgident, message_fname, message_fjoin, message_fmode,
- message_ftopic, message_opertype, message_idle, message_metadata,
- message_encap;
-
- InspIRCdProto ircd_proto;
- Inspircd20IRCdMessage ircd_message;
+ InspIRCd20Proto ircd_proto;
+
+ /* Core message handlers */
+ CoreIRCDMessageAway core_message_away;
+ CoreIRCDMessageCapab core_message_capab;
+ CoreIRCDMessageError core_message_error;
+ CoreIRCDMessageJoin core_message_join;
+ CoreIRCDMessageKill core_message_kill;
+ CoreIRCDMessageMOTD core_message_motd;
+ CoreIRCDMessagePart core_message_part;
+ CoreIRCDMessagePing core_message_ping;
+ CoreIRCDMessagePrivmsg core_message_privmsg;
+ CoreIRCDMessageQuit core_message_quit;
+ CoreIRCDMessageSQuit core_message_squit;
+ CoreIRCDMessageStats core_message_stats;
+ CoreIRCDMessageTopic core_message_topic;
+ CoreIRCDMessageVersion core_message_version;
+
+ /* inspircd-ts6.h message handlers */
+ IRCDMessageEndburst message_endburst;
+ IRCDMessageFHost message_fhost;
+ IRCDMessageFJoin message_sjoin;
+ IRCDMessageFMode message_fmode;
+ IRCDMessageFTopic message_ftopic;
+ IRCDMessageIdle message_idle;
+ IRCDMessageMetadata message_metadata;
+ IRCDMessageMode message_mode;
+ IRCDMessageNick message_nick;
+ IRCDMessageOperType message_opertype;
+ IRCDMessageRSQuit message_rsquit;
+ IRCDMessageServer message_server;
+ IRCDMessageTime message_time;
+ IRCDMessageUID message_uid;
+
+ /* Our message handlers */
+ IRCDMessageCapab message_capab;
+ IRCDMessageEncap message_encap;
+
public:
ProtoInspIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL),
- message_endburst("ENDBURST", event_endburst),
- message_time("TIME", event_time), message_rsquit("RSQUIT", event_rsquit),
- message_svsmode("SVSMODE", OnMode), message_fhost("FHOST", event_chghost),
- message_chgident("FIDENT", event_chgident), message_fname("FNAME", event_chgname),
- message_fjoin("FJOIN", OnSJoin),
- message_fmode("FMODE", event_fmode), message_ftopic("FTOPIC", event_ftopic),
- message_opertype("OPERTYPE", event_opertype), message_idle("IDLE", event_idle),
- message_metadata("METADATA", event_metadata), message_encap("ENCAP", event_encap)
+ message_fhost("FHOST")
{
this->SetAuthor("Anope");
- pmodule_ircd_var(&myIrcd);
- pmodule_ircd_proto(&this->ircd_proto);
- pmodule_ircd_message(&this->ircd_message);
-
Capab.insert("NOQUIT");
Implementation i[] = { I_OnUserNickChange, I_OnServerSync, I_OnChannelCreate, I_OnChanRegistered, I_OnDelChan, I_OnMLock, I_OnUnMLock };
@@ -740,13 +540,6 @@ class ProtoInspIRCd : public Module
it->second->GenerateUID();
}
- ~ProtoInspIRCd()
- {
- pmodule_ircd_var(NULL);
- pmodule_ircd_proto(NULL);
- pmodule_ircd_message(NULL);
- }
-
void OnUserNickChange(User *u, const Anope::string &) anope_override
{
u->RemoveModeInternal(ModeManager::FindUserModeByName(UMODE_REGISTERED));