ratbox.cpp

Go to the documentation of this file.
00001 /* Ratbox IRCD functions
00002  *
00003  * (C) 2003-2013 Anope Team
00004  * Contact us at team@anope.org
00005  *
00006  * Please read COPYING and README for further details.
00007  *
00008  * Based on the original code of Epona by Lara.
00009  * Based on the original code of Services by Andy Church.
00010  */
00011 
00012 #include "module.h"
00013 
00014 static Anope::string UplinkSID;
00015 
00016 static ServiceReference<IRCDProto> hybrid("IRCDProto", "hybrid");
00017 
00018 class RatboxProto : public IRCDProto
00019 {
00020  public:
00021         RatboxProto(Module *creator) : IRCDProto(creator, "Ratbox 3.0+")
00022         {
00023                 DefaultPseudoclientModes = "+oiS";
00024                 CanSNLine = true;
00025                 CanSQLine = true;
00026                 CanSZLine = true;
00027                 RequiresID = true;
00028                 MaxModes = 4;
00029         }
00030 
00031         void SendGlobalNotice(const BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override { hybrid->SendGlobalNotice(bi, dest, msg); }
00032         void SendGlobalPrivmsg(const BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override { hybrid->SendGlobalPrivmsg(bi, dest, msg); }
00033         void SendGlobopsInternal(const BotInfo *source, const Anope::string &buf) anope_override { hybrid->SendGlobopsInternal(source, buf); }
00034         void SendSQLine(User *u, const XLine *x) anope_override { hybrid->SendSQLine(u, x); }
00035         void SendSGLine(User *u, const XLine *x) anope_override { hybrid->SendSGLine(u, x); }
00036         void SendSGLineDel(const XLine *x) anope_override { hybrid->SendSGLineDel(x); }
00037         void SendAkill(User *u, XLine *x) anope_override { hybrid->SendAkill(u, x); }
00038         void SendAkillDel(const XLine *x) anope_override { hybrid->SendAkillDel(x); }
00039         void SendSQLineDel(const XLine *x) anope_override { hybrid->SendSQLineDel(x); }
00040         void SendJoin(const User *user, Channel *c, const ChannelStatus *status) anope_override { hybrid->SendJoin(user, c, status); }
00041         void SendServer(const Server *server) anope_override { hybrid->SendServer(server); }
00042         void SendModeInternal(const BotInfo *bi, const User *u, const Anope::string &buf) anope_override { hybrid->SendModeInternal(bi, u, buf); }
00043         void SendChannel(Channel *c) anope_override { hybrid->SendChannel(c); }
00044         void SendTopic(BotInfo *bi, Channel *c) anope_override { hybrid->SendTopic(bi, c); }
00045 
00046         void SendConnect() anope_override
00047         {
00048                 UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink]->password << " TS 6 :" << Me->GetSID();
00049                 /*
00050                   QS     - Can handle quit storm removal
00051                   EX     - Can do channel +e exemptions
00052                   CHW    - Can do channel wall @#
00053                   IE     - Can do invite exceptions
00054                   GLN    - Can do GLINE message
00055                   KNOCK  - supports KNOCK
00056                   TB     - supports topic burst
00057                   ENCAP  - supports ENCAP
00058                 */
00059                 UplinkSocket::Message() << "CAPAB :QS EX CHW IE GLN TB ENCAP";
00060                 /* Make myself known to myself in the serverlist */
00061                 SendServer(Me);
00062                 /*
00063                  * SVINFO
00064                  *        parv[0] = sender prefix
00065                  *        parv[1] = TS_CURRENT for the server
00066                  *        parv[2] = TS_MIN for the server
00067                  *        parv[3] = server is standalone or connected to non-TS only
00068                  *        parv[4] = server's idea of UTC time
00069                  */
00070                 UplinkSocket::Message() << "SVINFO 6 3 0 :" << Anope::CurTime;
00071         }
00072 
00073         void SendClientIntroduction(const User *u) anope_override
00074         {
00075                 Anope::string modes = "+" + u->GetModes();
00076                 UplinkSocket::Message(Me) << "UID " << u->nick << " 1 " << u->timestamp << " " << modes << " " << u->GetIdent() << " " << u->host << " 0 " << u->GetUID() << " :" << u->realname;
00077         }
00078 
00079         void SendLogin(User *u) anope_override
00080         {
00081                 if (!u->Account())
00082                         return;
00083 
00084                 UplinkSocket::Message(Me) << "ENCAP * SU " << u->GetUID() << " " << u->Account()->display;
00085         }
00086 
00087         void SendLogout(User *u) anope_override
00088         {
00089                 UplinkSocket::Message(Me) << "ENCAP * SU " << u->GetUID();
00090         }
00091 };
00092 
00093 struct IRCDMessageEncap : IRCDMessage
00094 {
00095         IRCDMessageEncap(Module *creator) : IRCDMessage(creator, "ENCAP", 3) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
00096 
00097         // Debug: Received: :00BAAAAAB ENCAP * LOGIN Adam
00098         void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
00099         {
00100                 if (params[1] == "LOGIN" || params[1] == "SU")
00101                 {
00102                         User *u = source.GetUser();
00103 
00104                         NickCore *nc = NickCore::Find(params[2]);
00105                         if (!nc)
00106                                 return;
00107                         u->Login(nc);
00108 
00109                         const NickAlias *user_na = NickAlias::Find(u->nick);
00110                         if (!Config->NoNicknameOwnership && user_na && user_na->nc == nc && user_na->nc->HasExt("UNCONFIRMED") == false)
00111                                 u->SetMode(NickServ, "REGISTERED");
00112                 }
00113         }
00114 };
00115 
00116 struct IRCDMessagePass : IRCDMessage
00117 {
00118         IRCDMessagePass(Module *creator) : IRCDMessage(creator, "PASS", 4) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
00119 
00120         void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
00121         {
00122                 UplinkSID = params[3];
00123         }
00124 };
00125 
00126 struct IRCDMessageServer : IRCDMessage
00127 {
00128         IRCDMessageServer(Module *creator) : IRCDMessage(creator, "SERVER", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
00129 
00130         // SERVER hades.arpa 1 :ircd-ratbox test server
00131         void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
00132         {
00133                 // Servers other then our immediate uplink are introduced via SID
00134                 if (params[1] != "1")
00135                         return;
00136                 new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], 1, params[2], UplinkSID);
00137                 IRCD->SendPing(Config->ServerName, params[0]);
00138         }
00139 };
00140 
00141 struct IRCDMessageTBurst : IRCDMessage
00142 {
00143         IRCDMessageTBurst(Module *creator) : IRCDMessage(creator, "TB", 3) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
00144 
00145         /*
00146          * params[0] = channel
00147          * params[1] = ts
00148          * params[2] = topic OR who set the topic
00149          * params[3] = topic if params[2] isnt the topic
00150          */
00151         void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
00152         {
00153                 time_t topic_time = Anope::string(params[1]).is_pos_number_only() ? convertTo<time_t>(params[1]) : Anope::CurTime;
00154                 Channel *c = Channel::Find(params[0]);
00155 
00156                 if (!c)
00157                         return;
00158 
00159                 const Anope::string &setter = params.size() == 4 ? params[2] : "",
00160                         topic = params.size() == 4 ? params[3] : params[2];
00161 
00162                 c->ChangeTopicInternal(setter, topic, topic_time);
00163         }
00164 };
00165 
00166 struct IRCDMessageUID : IRCDMessage
00167 {
00168         IRCDMessageUID(Module *creator) : IRCDMessage(creator, "UID", 9) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
00169 
00170         // :42X UID Adam 1 1348535644 +aow Adam 192.168.0.5 192.168.0.5 42XAAAAAB :Adam
00171         void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
00172         {
00173                 /* Source is always the server */
00174                 new User(params[0], params[4], params[5], "", params[6], source.GetServer(), params[8], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, params[3], params[7]);
00175         }
00176 };
00177 
00178 class ProtoRatbox : public Module
00179 {
00180         Module *m_hybrid;
00181 
00182         RatboxProto ircd_proto;
00183 
00184         /* Core message handlers */
00185         Message::Away message_away;
00186         Message::Capab message_capab;
00187         Message::Error message_error;
00188         Message::Kick message_kick;
00189         Message::Kill message_kill;
00190         Message::Mode message_mode;
00191         Message::MOTD message_motd;
00192         Message::Part message_part;
00193         Message::Ping message_ping;
00194         Message::Privmsg message_privmsg;
00195         Message::Quit message_quit;
00196         Message::SQuit message_squit;
00197         Message::Stats message_stats;
00198         Message::Time message_time;
00199         Message::Topic message_topic;
00200         Message::Version message_version;
00201         Message::Whois message_whois;
00202 
00203         /* Hybrid message handlers */
00204         ServiceAlias message_bmask, message_join, message_nick, message_pong, message_sid,
00205                         message_sjoin, message_tmode;
00206 
00207         /* Our message handlers */
00208         IRCDMessageEncap message_encap;
00209         IRCDMessagePass message_pass;
00210         IRCDMessageServer message_server;
00211         IRCDMessageTBurst message_tburst;
00212         IRCDMessageUID message_uid;
00213 
00214         void AddModes()
00215         {
00216                 /* user modes */
00217                 ModeManager::RemoveUserMode(ModeManager::FindUserModeByName("HIDEOPER"));
00218                 ModeManager::RemoveUserMode(ModeManager::FindUserModeByName("REGPRIV"));
00219 
00220                 /* v/h/o/a/q */
00221                 ModeManager::RemoveChannelMode(ModeManager::FindChannelModeByName("HALFOP"));
00222 
00223                 /* channel modes */
00224                 ModeManager::RemoveChannelMode(ModeManager::FindChannelModeByName("REGISTERED"));
00225                 ModeManager::RemoveChannelMode(ModeManager::FindChannelModeByName("OPERONLY"));
00226                 ModeManager::RemoveChannelMode(ModeManager::FindChannelModeByName("REGISTEREDONLY"));
00227                 ModeManager::RemoveChannelMode(ModeManager::FindChannelModeByName("SSL"));
00228         }
00229 
00230  public:
00231         ProtoRatbox(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL),
00232                 ircd_proto(this),
00233                 message_away(this), message_capab(this), message_error(this), message_kick(this), message_kill(this),
00234                 message_mode(this), message_motd(this), message_part(this), message_ping(this), message_privmsg(this),
00235                 message_quit(this), message_squit(this), message_stats(this), message_time(this), message_topic(this),
00236                 message_version(this), message_whois(this),
00237 
00238                 message_bmask("IRCDMessage", "ratbox/bmask", "hybrid/bmask"), message_join("IRCDMessage", "ratbox/join", "hybrid/join"),
00239                 message_nick("IRCDMessage", "ratbox/nick", "hybrid/nick"), message_pong("IRCDMessage", "ratbox/pong", "hybrid/pong"),
00240                 message_sid("IRCDMessage", "ratbox/sid", "hybrid/sid"), message_sjoin("IRCDMessage", "ratbox/sjoin", "hybrid/sjoin"),
00241                 message_tmode("IRCDMessage", "ratbox/tmode", "hybrid/tmode"),
00242 
00243                 message_encap(this), message_pass(this), message_server(this), message_tburst(this), message_uid(this)
00244         {
00245                 this->SetAuthor("Anope");
00246 
00247                 if (ModuleManager::LoadModule("hybrid", User::Find(creator)) != MOD_ERR_OK)
00248                         throw ModuleException("Unable to load hybrid");
00249                 m_hybrid = ModuleManager::FindModule("hybrid");
00250                 if (!m_hybrid)
00251                         throw ModuleException("Unable to find hybrid");
00252                 if (!hybrid)
00253                         throw ModuleException("No protocol interface for hybrid");
00254 
00255                 this->AddModes();
00256         }
00257 
00258         ~ProtoRatbox()
00259         {
00260                 ModuleManager::UnloadModule(m_hybrid, NULL);
00261         }
00262 };
00263 
00264 MODULE_INIT(ProtoRatbox)