diff options
Diffstat (limited to 'modules/protocol')
| -rw-r--r-- | modules/protocol/bahamut.cpp | 322 | ||||
| -rw-r--r-- | modules/protocol/inspircd-ts6.h | 386 | ||||
| -rw-r--r-- | modules/protocol/inspircd11.cpp | 571 | ||||
| -rw-r--r-- | modules/protocol/inspircd12.cpp | 389 | ||||
| -rw-r--r-- | modules/protocol/inspircd20.cpp | 399 | ||||
| -rw-r--r-- | modules/protocol/plexus.cpp | 538 | ||||
| -rw-r--r-- | modules/protocol/ratbox.cpp | 445 | ||||
| -rw-r--r-- | modules/protocol/unreal.cpp | 783 |
8 files changed, 1848 insertions, 1985 deletions
diff --git a/modules/protocol/bahamut.cpp b/modules/protocol/bahamut.cpp index 73955149d..8aeee39c8 100644 --- a/modules/protocol/bahamut.cpp +++ b/modules/protocol/bahamut.cpp @@ -13,34 +13,40 @@ #include "module.h" -IRCDVar myIrcd = { - "Bahamut 1.8.x", /* ircd name */ - "+", /* Modes used by pseudoclients */ - 1, /* SVSNICK */ - 0, /* Vhost */ - 1, /* Supports SNlines */ - 1, /* Supports SQlines */ - 1, /* Supports SZlines */ - 0, /* Join 2 Message */ - 1, /* Chan SQlines */ - 1, /* Quit on Kill */ - 0, /* vidents */ - 1, /* svshold */ - 1, /* 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 */ - 0, /* ts6 */ - "$", /* TLD Prefix for Global */ - 6, /* Max number of modes we can send per line */ - 0 /* IRCd sends a SSL users certificate fingerprint */ -}; +class ChannelModeFlood : public ChannelModeParam +{ + public: + ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam(CMODE_FLOOD, modeChar, minusNoArg) { } + bool IsValid(const Anope::string &value) const anope_override + { + try + { + Anope::string rest; + if (!value.empty() && value[0] != ':' && convertTo<int>(value[0] == '*' ? value.substr(1) : value, rest, false) > 0 && rest[0] == ':' && rest.length() > 1 && convertTo<int>(rest.substr(1), rest, false) > 0 && rest.empty()) + return true; + } + catch (const ConvertException &) { } + + return false; + } +}; class BahamutIRCdProto : public IRCDProto { + public: + BahamutIRCdProto() : IRCDProto("Bahamut 1.8.x") + { + DefaultPseudoclientModes = "+"; + CanSVSNick = true; + CanSNLine = true; + CanSQLine = true; + CanSQLineChannel = true; + CanSZLine = true; + CanSVSHold = true; + MaxModes = 60; + } + void SendModeInternal(const BotInfo *source, const Channel *dest, const Anope::string &buf) anope_override { if (Capab.count("TSMODE") > 0) @@ -62,6 +68,16 @@ class BahamutIRCdProto : public IRCDProto UplinkSocket::Message(Me) << "SVSMODE " << u->nick << " " << u->timestamp << " " << buf; } + void SendGlobalNotice(const BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override + { + UplinkSocket::Message(bi) << "NOTICE $" << dest->GetName() << " :" << msg; + } + + void SendGlobalPrivmsg(const BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override + { + UplinkSocket::Message(bi) << "PRIVMSG $" << dest->GetName() << " :" << msg; + } + /* SVSHOLD - set */ void SendSVSHold(const Anope::string &nick) anope_override { @@ -290,46 +306,82 @@ class BahamutIRCdProto : public IRCDProto } }; -class BahamutIRCdMessage : public IRCdMessage +struct IRCDMessageBurst : IRCDMessage { - public: - bool OnMode(const Anope::string &source, const std::vector<Anope::string> ¶ms) anope_override - { - if (params.size() > 2 && (params[0][0] == '#' || params[0][0] == '&')) - do_cmode(source, params[0], params[2], params[1]); - else if (params.size() > 1) - do_umode(params[0], params[1]); + IRCDMessageBurst() : IRCDMessage("BURST", 0) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); } + bool Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + /* If we found a server with the given source, that one just + * finished bursting. If there was no source, then our uplink + * server finished bursting. -GD + */ + Server *s = source.GetServer(); + if (!s) + s = Me->GetLinks().front(); + if (s) + s->Sync(true); return true; } +}; - /* - ** NICK - new - ** source = NULL - ** parv[0] = nickname - ** parv[1] = hopcount - ** parv[2] = timestamp - ** parv[3] = modes - ** parv[4] = username - ** parv[5] = hostname - ** parv[6] = server - ** parv[7] = servicestamp - ** parv[8] = IP - ** parv[9] = info - ** NICK - change - ** source = oldnick - ** parv[0] = new nickname - ** parv[1] = hopcount - */ - bool OnNick(const Anope::string &source, const std::vector<Anope::string> ¶ms) anope_override - { - if (params.size() != 2) +struct IRCDMessageMode : IRCDMessage +{ + IRCDMessageMode(const Anope::string &n) : IRCDMessage(n, 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } + + bool Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + if (params.size() > 2 && ircdproto->IsChannelValid(params[0])) + { + Channel *c = findchan(params[0]); + time_t ts = Anope::CurTime; + try + { + ts = convertTo<time_t>(params[1]); + } + catch (const ConvertException &) { } + + if (c) + c->SetModesInternal(source, params[2], ts); + } + else { - /* Currently bahamut has no ipv6 support */ - sockaddrs ip; - ip.ntop(AF_INET, params[8].c_str()); + User *u = finduser(params[0]); + if (u) + u->SetModesInternal("%s", params[1].c_str()); + } + + return true; + } +}; + +/* + ** NICK - new + ** source = NULL + ** parv[0] = nickname + ** parv[1] = hopcount + ** parv[2] = timestamp + ** parv[3] = modes + ** parv[4] = username + ** parv[5] = hostname + ** parv[6] = server + ** parv[7] = servicestamp + ** parv[8] = IP + ** parv[9] = info + ** NICK - change + ** source = oldnick + ** parv[0] = new nickname + ** parv[1] = hopcount + */ +struct IRCDMessageNick : IRCDMessage +{ + IRCDMessageNick() : IRCDMessage("NICK", 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } - User *user = do_nick(source, params[0], params[4], params[5], params[6], params[9], Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, ip.addr(), "", "", params[3]); + bool Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + if (params.size() == 10) + { + User *user = new User(params[0], params[4], params[5], "", params[8], source.GetServer(), params[9], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, params[3]); if (user && nickserv) { const NickAlias *na; @@ -345,35 +397,29 @@ class BahamutIRCdMessage : public IRCdMessage } } else - do_nick(source, params[0], "", "", "", "", Anope::string(params[1]).is_pos_number_only() ? convertTo<time_t>(params[1]) : 0, "", "", "", ""); + source.GetUser()->ChangeNick(params[0]); return true; } +}; - bool OnServer(const Anope::string &source, const std::vector<Anope::string> ¶ms) anope_override - { - do_server(source, params[0], Anope::string(params[1]).is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0, params[2], ""); - return true; - } +struct IRCDMessageServer : IRCDMessage +{ + IRCDMessageServer() : IRCDMessage("SERVER", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); } - bool OnTopic(const Anope::string &, const std::vector<Anope::string> ¶ms) anope_override + bool Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override { - if (params.size() < 4) - return true; - - Channel *c = findchan(params[0]); - if (!c) - { - Log() << "TOPIC for nonexistant channel " << params[0]; - return true; - } - - c->ChangeTopicInternal(params[1], params[3], Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : Anope::CurTime); - + unsigned int hops = Anope::string(params[1]).is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0; + new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], hops, params[2]); return true; } +}; - bool OnSJoin(const Anope::string &source, const std::vector<Anope::string> ¶ms) anope_override +struct IRCDMessageSJoin : IRCDMessage +{ + IRCDMessageSJoin() : IRCDMessage("SJOIN", 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); SetFlag(IRCDMESSAGE_REQUIRE_SERVER); } + + bool Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override { Channel *c = findchan(params[1]); time_t ts = Anope::string(params[0]).is_pos_number_only() ? convertTo<time_t>(params[0]) : 0; @@ -403,7 +449,7 @@ class BahamutIRCdMessage : public IRCdMessage modes += " " + params[i]; if (!modes.empty()) modes.erase(modes.begin()); - c->SetModesInternal(NULL, modes); + c->SetModesInternal(source, modes); } /* For some reason, bahamut will send a SJOIN from the user joining a channel @@ -411,28 +457,24 @@ class BahamutIRCdMessage : public IRCdMessage */ if (!c->HasFlag(CH_SYNCING) && params.size() == 2) { - User *u = finduser(source); - if (!u) - Log(LOG_DEBUG) << "SJOIN for nonexistant user " << source << " on " << c->name; - else - { - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnPreJoinChannel, OnPreJoinChannel(u, c)); + User *u = source.GetUser(); - /* Add the user to the channel */ - c->JoinUser(u); + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnPreJoinChannel, OnPreJoinChannel(u, c)); - /* Now set whatever modes this user is allowed to have on the channel */ - chan_set_correct_modes(u, c, 1, true); + /* Add the user to the channel */ + c->JoinUser(u); - /* Check to see if modules want the user to join, if they do - * check to see if they are allowed to join (CheckKick will kick/ban them) - * Don't trigger OnJoinChannel event then as the user will be destroyed - */ - if (MOD_RESULT == EVENT_STOP && (!c->ci || !c->ci->CheckKick(u))) - { - FOREACH_MOD(I_OnJoinChannel, OnJoinChannel(u, c)); - } + /* Now set whatever modes this user is allowed to have on the channel */ + chan_set_correct_modes(u, c, 1, true); + + /* Check to see if modules want the user to join, if they do + * check to see if they are allowed to join (CheckKick will kick/ban them) + * Don't trigger OnJoinChannel event then as the user will be destroyed + */ + if (MOD_RESULT == EVENT_STOP && (!c->ci || !c->ci->CheckKick(u))) + { + FOREACH_MOD(I_OnJoinChannel, OnJoinChannel(u, c)); } } else @@ -476,7 +518,7 @@ class BahamutIRCdMessage : public IRCdMessage * This will enforce secureops etc on the user */ for (std::list<ChannelMode *>::iterator it = Status.begin(), it_end = Status.end(); it != it_end; ++it) - c->SetModeInternal(NULL, *it, buf); + c->SetModeInternal(source, *it, buf); /* Now set whatever modes this user is allowed to have on the channel */ chan_set_correct_modes(u, c, 1, true); @@ -504,53 +546,48 @@ class BahamutIRCdMessage : public IRCdMessage } }; -bool event_burst(const Anope::string &source, const std::vector<Anope::string> ¶ms) -{ - Server *s = Server::Find(source); - - if (params.empty()) - { - /* for future use - start burst */ - } - else - { - /* If we found a server with the given source, that one just - * finished bursting. If there was no source, then our uplink - * server finished bursting. -GD - */ - if (!s) - s = Me->GetLinks().front(); - if (s) - s->Sync(true); - } - return true; -} - -class ChannelModeFlood : public ChannelModeParam +struct IRCDMessageTopic : IRCDMessage { - public: - ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam(CMODE_FLOOD, modeChar, minusNoArg) { } + IRCDMessageTopic() : IRCDMessage("TOPIC", 4) { } - bool IsValid(const Anope::string &value) const anope_override + bool Run(MessageSource &, const std::vector<Anope::string> ¶ms) anope_override { - try - { - Anope::string rest; - if (!value.empty() && value[0] != ':' && convertTo<int>(value[0] == '*' ? value.substr(1) : value, rest, false) > 0 && rest[0] == ':' && rest.length() > 1 && convertTo<int>(rest.substr(1), rest, false) > 0 && rest.empty()) - return true; - } - catch (const ConvertException &) { } - - return false; + Channel *c = findchan(params[0]); + if (c) + c->ChangeTopicInternal(params[1], params[3], Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : Anope::CurTime); + return true; } }; class ProtoBahamut : public Module { - Message message_svsmode, message_burst; - BahamutIRCdProto ircd_proto; - BahamutIRCdMessage ircd_message; + + /* 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; + CoreIRCDMessageTime core_message_time; + CoreIRCDMessageTopic core_message_topic; + CoreIRCDMessageVersion core_message_version; + CoreIRCDMessageWhois core_message_whois; + + /* Our message handlers */ + IRCDMessageBurst message_burst; + IRCDMessageMode message_mode, message_svsmode; + IRCDMessageNick message_nick; + IRCDMessageServer message_server; + IRCDMessageSJoin message_sjoin; + IRCDMessageTopic message_topic; void AddModes() { @@ -591,26 +628,15 @@ class ProtoBahamut : public Module public: ProtoBahamut(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL), - message_svsmode("SVSMODE", OnMode), message_burst("BURST", event_burst) + message_mode("MODE"), message_svsmode("SVSMODE") { this->SetAuthor("Anope"); - pmodule_ircd_var(&myIrcd); - pmodule_ircd_proto(&this->ircd_proto); - pmodule_ircd_message(&this->ircd_message); - this->AddModes(); ModuleManager::Attach(I_OnUserNickChange, this); } - ~ProtoBahamut() - { - 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)); diff --git a/modules/protocol/inspircd-ts6.h b/modules/protocol/inspircd-ts6.h index 0ce5be921..f0af01cc9 100644 --- a/modules/protocol/inspircd-ts6.h +++ b/modules/protocol/inspircd-ts6.h @@ -47,7 +47,30 @@ class InspIRCdTS6Proto : public IRCDProto UplinkSocket::Message(Me) << "CHGHOST " << nick << " " << vhost; } - public: + protected: + InspIRCdTS6Proto(const Anope::string &name) : IRCDProto(name) + { + DefaultPseudoclientModes = "+I"; + CanSVSNick = true; + CanSetVHost = true; + CanSetVIdent = true; + CanSQLine = true; + CanSZLine = true; + CanSVSHold = true; + CanCertFP = true; + RequiresID = true; + MaxModes = 20; + } + + void SendGlobalNotice(const BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override + { + UplinkSocket::Message(bi) << "NOTICE $" << dest->GetName() << " :" << msg; + } + + void SendGlobalPrivmsg(const BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override + { + UplinkSocket::Message(bi) << "PRIVMSG $" << dest->GetName() << " :" << msg; + } void SendAkillDel(const XLine *x) anope_override { @@ -225,7 +248,7 @@ class InspIRCdTS6Proto : public IRCDProto SendServer(Me); UplinkSocket::Message(Me) << "BURST"; Module *enc = ModuleManager::FindFirstOf(ENCRYPTION); - UplinkSocket::Message(Me) << "VERSION :Anope-" << Anope::Version() << " " << Config->ServerName << " :" << ircd->name << " - (" << (enc ? enc->name : "unknown") << ") -- " << Anope::VersionBuildString(); + UplinkSocket::Message(Me) << "VERSION :Anope-" << Anope::Version() << " " << Config->ServerName << " :" << ircdproto->GetProtocolName() << " - (" << (enc ? enc->name : "unknown") << ") -- " << Anope::VersionBuildString(); } /* SVSHOLD - set */ @@ -319,83 +342,37 @@ class InspIRCdTS6Proto : public IRCDProto } }; -class InspircdIRCdMessage : public IRCdMessage +struct IRCDMessageEndburst : IRCDMessage { - public: - bool OnMode(const Anope::string &source, const std::vector<Anope::string> ¶ms) anope_override - { - if (params[0][0] == '#' || params[0][0] == '&') - do_cmode(source, params[0], params[2], params[1]); - else - { - /* InspIRCd lets opers change another - users modes, we have to kludge this - as it slightly breaks RFC1459 - */ - User *u = finduser(source); - // This can happen with server-origin modes. - if (!u) - u = finduser(params[0]); - // if it's still null, drop it like fire. - // most likely situation was that server introduced a nick which we subsequently akilled - if (!u) - return true; + IRCDMessageEndburst() : IRCDMessage("ENDBURST", 0) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); } - do_umode(u->nick, params[1]); - } - - return true; - } - - virtual bool OnUID(const Anope::string &source, const std::vector<Anope::string> ¶ms) anope_override = 0; - - bool OnNick(const Anope::string &source, const std::vector<Anope::string> ¶ms) anope_override + bool Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override { - do_nick(source, params[0], "", "", "", "", 0, "", "", "", ""); - return true; - } - - bool OnPrivmsg(const Anope::string &source, const std::vector<Anope::string> ¶ms) anope_override - { - /* Ignore privmsgs from the server, which can happen. */ - if (Server::Find(source) != NULL) - return true; + Server *s = source.GetServer(); - return IRCdMessage::OnPrivmsg(source, params); - } + Log(LOG_DEBUG) << "Processed ENDBURST for " << s->GetName(); - /* - * [Nov 04 00:08:46.308435 2009] debug: Received: SERVER irc.inspircd.com pass 0 964 :Testnet Central! - * 0: name - * 1: pass - * 2: hops - * 3: numeric - * 4: desc - */ - bool OnServer(const Anope::string &source, const std::vector<Anope::string> ¶ms) anope_override - { - do_server(source, params[0], Anope::string(params[2]).is_pos_number_only() ? convertTo<unsigned>(params[2]) : 0, params[4], params[3]); + s->Sync(true); return true; } +}; - bool OnTopic(const Anope::string &source, const std::vector<Anope::string> ¶ms) anope_override - { - Channel *c = findchan(params[0]); - - if (!c) - { - Log() << "TOPIC " << params[1] << " for nonexistent channel " << params[0]; - return true; - } - - c->ChangeTopicInternal(source, (params.size() > 1 ? params[1] : ""), Anope::CurTime); +struct IRCDMessageFHost : IRCDMessage +{ + IRCDMessageFHost(const Anope::string &n) : IRCDMessage(n, 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); } + bool Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + source.GetUser()->SetDisplayedHost(params[0]); return true; } +}; - virtual bool OnCapab(const Anope::string &, const std::vector<Anope::string> &) anope_override = 0; +struct IRCDMessageFJoin : IRCDMessage +{ + IRCDMessageFJoin() : IRCDMessage("FJOIN", 2) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); } - bool OnSJoin(const Anope::string &source, const std::vector<Anope::string> ¶ms) anope_override + bool Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override { Channel *c = findchan(params[0]); time_t ts = Anope::string(params[1]).is_pos_number_only() ? convertTo<time_t>(params[1]) : 0; @@ -425,7 +402,7 @@ class InspircdIRCdMessage : public IRCdMessage if (!modes.empty()) modes.erase(modes.begin()); /* Set the modes internally */ - c->SetModesInternal(NULL, modes); + c->SetModesInternal(source, modes); } spacesepstream sep(params[params.size() - 1]); @@ -468,7 +445,7 @@ class InspircdIRCdMessage : public IRCdMessage * This will enforce secureops etc on the user */ for (std::list<ChannelMode *>::iterator it = Status.begin(), it_end = Status.end(); it != it_end; ++it) - c->SetModeInternal(NULL, *it, buf); + c->SetModeInternal(source, *it, buf); /* Now set whatever modes this user is allowed to have on the channel */ chan_set_correct_modes(u, c, 1, true); @@ -495,33 +472,268 @@ class InspircdIRCdMessage : public IRCdMessage } }; -bool event_idle(const Anope::string &source, const std::vector<Anope::string> ¶ms) +struct IRCDMessageFMode : IRCDMessage +{ + IRCDMessageFMode() : IRCDMessage("FMODE", 3) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } + + bool Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + /* :source FMODE #test 12345678 +nto foo */ + + Anope::string modes = params[2]; + for (unsigned n = 3; n < params.size(); ++n) + modes += " " + params[n]; + + Channel *c = findchan(params[0]); + time_t ts; + + try + { + ts = convertTo<time_t>(params[1]); + } + catch (const ConvertException &) + { + ts = Anope::CurTime; + } + + if (c) + c->SetModesInternal(source, modes, ts); + + return true; + } +}; + +struct IRCDMessageFTopic : IRCDMessage +{ + IRCDMessageFTopic() : IRCDMessage("FTOPIC", 4) { } + + bool Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + /* :source FTOPIC channel ts setby :topic */ + + Channel *c = findchan(params[0]); + if (c) + c->ChangeTopicInternal(params[2], params[3], Anope::string(params[1]).is_pos_number_only() ? convertTo<time_t>(params[1]) : Anope::CurTime); + + return true; + } +}; + +struct IRCDMessageIdle : IRCDMessage +{ + IRCDMessageIdle() : IRCDMessage("IDLE", 1) { } + + bool Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + const BotInfo *bi = findbot(params[0]); + if (bi) + UplinkSocket::Message(bi) << "IDLE " << source.GetSource() << " " << start_time << " " << (Anope::CurTime - bi->lastmsg); + return true; + } +}; + +/* + * source = numeric of the sending server + * params[0] = uuid + * params[1] = metadata name + * params[2] = data + */ +struct IRCDMessageMetadata : IRCDMessage +{ + IRCDMessageMetadata() : IRCDMessage("METADATA", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); } + + bool Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + 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; + } +}; + +struct IRCDMessageMode : IRCDMessage +{ + IRCDMessageMode() : IRCDMessage("MODE", 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } + + bool Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + if (ircdproto->IsChannelValid(params[0])) + { + Channel *c = findchan(params[0]); + time_t ts; + + try + { + ts = convertTo<time_t>(params[1]); + } + catch (const ConvertException &) + { + ts = Anope::CurTime; + } + + if (c) + c->SetModesInternal(source, params[2], ts); + } + else + { + /* InspIRCd lets opers change another + users modes, we have to kludge this + as it slightly breaks RFC1459 + */ + User *u = source.GetUser(); + // This can happen with server-origin modes. + if (!u) + u = finduser(params[0]); + // if it's still null, drop it like fire. + // most likely situation was that server introduced a nick which we subsequently akilled + if (u) + u->SetModesInternal("%s", params[1].c_str()); + } + + return true; + } +}; + +struct IRCDMessageNick : IRCDMessage +{ + IRCDMessageNick() : IRCDMessage("NICK", 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); } + + bool Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + source.GetUser()->ChangeNick(params[0]); + return true; + } +}; + +struct IRCDMessageOperType : IRCDMessage +{ + IRCDMessageOperType() : IRCDMessage("OPERTYPE", 0) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); SetFlag(IRCDMESSAGE_REQUIRE_USER); } + + bool Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + /* opertype is equivalent to mode +o because servers + dont do this directly */ + User *u = source.GetUser(); + if (!u->HasMode(UMODE_OPER)) + u->SetModesInternal("+o"); + + return true; + } +}; + +struct IRCDMessageRSQuit : IRCDMessage { - const BotInfo *bi = findbot(params[0]); - if (bi) - UplinkSocket::Message(bi) << "IDLE " << source << " " << start_time << " " << (Anope::CurTime - bi->lastmsg); - return true; -} + IRCDMessageRSQuit() : IRCDMessage("RSQUIT", 1) { } + + bool Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + Server *s = Server::Find(params[0]); + if (!s) + return true; + + /* On InspIRCd we must send a SQUIT when we recieve RSQUIT for a server we have juped */ + if (s->HasFlag(SERVER_JUPED)) + UplinkSocket::Message(Me) << "SQUIT " << s->GetSID() << " :" << (params.size() > 1 ? params[1].c_str() : ""); + + FOREACH_MOD(I_OnServerQuit, OnServerQuit(s)); + + s->Delete(s->GetName() + " " + s->GetUplink()->GetName()); + + return true; + } +}; -bool event_time(const Anope::string &source, const std::vector<Anope::string> ¶ms) +struct IRCDMessageServer : IRCDMessage { - if (params.size() < 2) + IRCDMessageServer() : IRCDMessage("SERVER", 5) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); } + + /* + * [Nov 04 00:08:46.308435 2009] debug: Received: SERVER irc.inspircd.com pass 0 964 :Testnet Central! + * 0: name + * 1: pass + * 2: hops + * 3: numeric + * 4: desc + */ + bool Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + unsigned int hops = Anope::string(params[2]).is_pos_number_only() ? convertTo<unsigned>(params[2]) : 0; + new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], hops, params[4], params[3]); return true; + } +}; - UplinkSocket::Message(Me) << "TIME " << source << " " << params[1] << " " << Anope::CurTime; - return true; -} +struct IRCDMessageTime : IRCDMessage +{ + IRCDMessageTime() : IRCDMessage("TIME", 2) { } + + bool Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + UplinkSocket::Message(Me) << "TIME " << source.GetSource() << " " << params[1] << " " << Anope::CurTime; + return true; + } +}; -bool event_rsquit(const Anope::string &source, const std::vector<Anope::string> ¶ms) +struct IRCDMessageUID : IRCDMessage { - /* On InspIRCd we must send a SQUIT when we recieve RSQUIT for a server we have juped */ - Server *s = Server::Find(params[0]); - if (s && s->HasFlag(SERVER_JUPED)) - UplinkSocket::Message(Me) << "SQUIT " << s->GetSID() << " :" << (params.size() > 1 ? params[1].c_str() : ""); + IRCDMessageUID() : IRCDMessage("UID", 8) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); } + + /* + * [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 Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + time_t ts = convertTo<time_t>(params[1]); - ircdmessage->OnSQuit(source, params); + Anope::string modes = params[8]; + for (unsigned i = 9; i < params.size() - 1; ++i) + modes += " " + params[i]; - return true; -} + User *u = new User(params[2], params[5], params[3], params[4], params[6], source.GetServer(), params[params.size() - 1], ts, modes, params[0]); + if (u->server->IsSynced() && nickserv) + nickserv->Validate(u); + return true; + } +}; diff --git a/modules/protocol/inspircd11.cpp b/modules/protocol/inspircd11.cpp index 7470d61aa..1eba8321f 100644 --- a/modules/protocol/inspircd11.cpp +++ b/modules/protocol/inspircd11.cpp @@ -13,31 +13,6 @@ #include "module.h" -IRCDVar myIrcd = { - "InspIRCd 1.1", /* ircd name */ - "+I", /* Modes used by pseudoclients */ - 1, /* SVSNICK */ - 1, /* Vhost */ - 1, /* Supports SNlines */ - 1, /* Supports SQlines */ - 1, /* Supports SZlines */ - 1, /* Join 2 Message */ - 0, /* Chan SQlines */ - 0, /* Quit on Kill */ - 1, /* vidents */ - 1, /* svshold */ - 0, /* time stamp on mode */ - 1, /* 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 */ - 0, /* ts6 */ - "$", /* TLD Prefix for Global */ - 20, /* Max number of modes we can send per line */ - 0 /* IRCd sends a SSL users certificate fingerprint */ -}; - static bool has_servicesmod = false; static bool has_globopsmod = false; static bool has_svsholdmod = false; @@ -45,40 +20,60 @@ static bool has_chghostmod = false; static bool has_chgidentmod = false; static bool has_hidechansmod = false; -/* CHGHOST */ -void inspircd_cmd_chghost(const Anope::string &nick, const Anope::string &vhost) +class InspIRCdProto : public IRCDProto { - const BotInfo *bi = findbot(Config->OperServ); - if (has_chghostmod) + public: + InspIRCdProto() : IRCDProto("InspIRCd 1.1") { - if (nick.empty() || vhost.empty()) - return; - UplinkSocket::Message(bi) << "CHGHOST " << nick << " " << vhost; + DefaultPseudoclientModes = "+I"; + CanSVSNick = true; + CanSetVHost = true; + CanSetVIdent = true; + CanSNLine = true; + CanSQLine = true; + CanSZLine = true; + CanSVSHold = true; + CanSVSO = true; + MaxModes = 20; } - else + private: + + Anope::string current_pass; + + void inspircd_cmd_chgident(const Anope::string &nick, const Anope::string &vIdent) { - if (bi) - ircdproto->SendGlobops(bi, "CHGHOST not loaded!"); + if (has_chgidentmod) + { + if (nick.empty() || vIdent.empty()) + return; + UplinkSocket::Message(findbot(Config->OperServ)) << "CHGIDENT " << nick << " " << vIdent; + } + else + Log() << "CHGIDENT not loaded!"; } -} -bool event_idle(const Anope::string &source, const std::vector<Anope::string> ¶ms) -{ - const BotInfo *bi = findbot(params[0]); - UplinkSocket::Message(bi) << "IDLE " << source << " " << start_time << " " << (bi ? Anope::CurTime - bi->lastmsg : 0); - return true; -} + void inspircd_cmd_chghost(const Anope::string &nick, const Anope::string &vhost) + { + if (has_chghostmod) + { + if (nick.empty() || vhost.empty()) + return; + UplinkSocket::Message(findbot(Config->OperServ)) << "CHGHOST " << nick << " " << vhost; + } + else + Log() << "CHGHOST not loaded!"; + } -static Anope::string currentpass; + void SendGlobalNotice(const BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override + { + UplinkSocket::Message(bi) << "NOTICE $" << dest->GetName() << " :" << msg; + } -/* PASS */ -void inspircd_cmd_pass(const Anope::string &pass) -{ - currentpass = pass; -} + void SendGlobalPrivmsg(const BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override + { + UplinkSocket::Message(bi) << "PRIVMSG $" << dest->GetName() << " :" << msg; + } -class InspIRCdProto : public IRCDProto -{ void SendAkillDel(const XLine *x) anope_override { if (x->IsRegex() || x->HasNickOrReal()) @@ -159,12 +154,18 @@ class InspIRCdProto : public IRCDProto UplinkSocket::Message(Me) << "ADDLINE G " << x->Mask << " " << x->By << " " << Anope::CurTime << " " << timeleft << " :" << x->GetReason(); } - void SendSVSKillInternal(const BotInfo *source, const User *user, const Anope::string &buf) anope_override + void SendSVSKillInternal(const BotInfo *source, User *user, cons |
