diff options
| author | Adam <Adam@anope.org> | 2012-10-01 01:56:57 -0400 |
|---|---|---|
| committer | Adam <Adam@anope.org> | 2012-10-01 01:56:57 -0400 |
| commit | 89428a9d1032e3c2a6e397629a32862b3e58d708 (patch) | |
| tree | d507904b3fa1cc084f0f3e688c839bcdd47f79d7 /modules/protocol/inspircd20.cpp | |
| parent | b937d6310d9a7c0e2434200306b63d513cb2ae61 (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.cpp | 399 |
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> ¶ms) -{ - /* :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> ¶ms) -{ - /* 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> ¶ms) -{ - /* :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> ¶ms) -{ - 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> ¶ms) -{ - 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> ¶ms) -{ - 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> ¶ms) -{ - 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> ¶ms) -{ - 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> ¶ms) -{ - 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> ¶ms) 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> ¶ms) anope_override + bool Run(MessageSource &source, const std::vector<Anope::string> ¶ms) 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> ¶ms) 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)); |
