operserv.cpp

Go to the documentation of this file.
00001 /* OperServ core functions
00002  *
00003  * (C) 2003-2012 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 /*************************************************************************/
00013 
00014 #include "module.h"
00015 
00016 class SGLineManager : public XLineManager
00017 {
00018  public:
00019         SGLineManager(Module *creator) : XLineManager(creator, "xlinemanager/sgline", 'G') { }
00020 
00021         void OnMatch(User *u, XLine *x) anope_override
00022         {
00023                 this->Send(u, x);
00024         }
00025 
00026         void OnExpire(const XLine *x) anope_override
00027         {
00028                 Log(findbot(Config->OperServ), "expire/akill") << "AKILL on \2" << x->Mask << "\2 has expired";
00029         }
00030         
00031         void Send(User *u, XLine *x) anope_override
00032         {
00033                 ircdproto->SendAkill(u, x);
00034         }
00035 
00036         void SendDel(XLine *x) anope_override
00037         {
00038                 try
00039                 {
00040                         if (!ircdproto->CanSZLine)
00041                                 throw SocketException("SZLine is not supported");
00042                         else if (x->GetUser() != "*")
00043                                 throw SocketException("Can not ZLine a username");
00044                         sockaddrs(x->GetHost());
00045                         ircdproto->SendSZLineDel(x);
00046                 }
00047                 catch (const SocketException &)
00048                 {
00049                         ircdproto->SendAkillDel(x);
00050                 }
00051         }
00052 
00053         bool Check(User *u, const XLine *x) anope_override
00054         {
00055                 if (x->regex)
00056                 {
00057                         Anope::string uh = u->GetIdent() + "@" + u->host, nuhr = u->nick + "!" + uh + "#" + u->realname;
00058                         if (x->regex->Matches(uh) || x->regex->Matches(nuhr))
00059                                 return true;
00060 
00061                         return false;
00062                 }
00063 
00064                 if (!x->GetNick().empty() && !Anope::Match(u->nick, x->GetNick()))
00065                         return false;
00066 
00067                 if (!x->GetUser().empty() && !Anope::Match(u->GetIdent(), x->GetUser()))
00068                         return false;
00069 
00070                 if (!x->GetReal().empty() && !Anope::Match(u->realname, x->GetReal()))
00071                         return false;
00072 
00073                 if (!x->GetHost().empty())
00074                 {
00075                         try
00076                         {
00077                                 cidr cidr_ip(x->GetHost());
00078                                 sockaddrs ip(u->ip);
00079                                 if (cidr_ip.match(ip))
00080                                         return true;
00081                         }
00082                         catch (const SocketException &) { }
00083                 }
00084 
00085                 if (x->GetHost().empty() || Anope::Match(u->host, x->GetHost()))
00086                         return true;
00087 
00088                 return false;
00089         }
00090 };
00091 
00092 class SQLineManager : public XLineManager
00093 {
00094  public:
00095         SQLineManager(Module *creator) : XLineManager(creator, "xlinemanager/sqline", 'Q') { }
00096 
00097         void OnMatch(User *u, XLine *x) anope_override
00098         {
00099                 this->Send(u, x);
00100         }
00101 
00102         void OnExpire(const XLine *x) anope_override
00103         {
00104                 Log(findbot(Config->OperServ), "expire/sqline") << "SQLINE on \2" << x->Mask << "\2 has expired";
00105         }
00106 
00107         void Send(User *u, XLine *x) anope_override
00108         {
00109                 ircdproto->SendSQLine(u, x);
00110         }
00111 
00112         void SendDel(XLine *x) anope_override
00113         {
00114                 ircdproto->SendSQLineDel(x);
00115         }
00116 
00117         bool Check(User *u, const XLine *x) anope_override
00118         {
00119                 if (x->regex)
00120                         return x->regex->Matches(u->nick);
00121                 return Anope::Match(u->nick, x->Mask);
00122         }
00123 
00124         bool CheckChannel(Channel *c)
00125         {
00126                 for (std::vector<XLine *>::const_iterator it = this->GetList().begin(), it_end = this->GetList().end(); it != it_end; ++it)
00127                         if (Anope::Match(c->name, (*it)->Mask, false, true))
00128                                 return true;
00129                 return false;
00130         }
00131 };
00132 
00133 class SNLineManager : public XLineManager
00134 {
00135  public:
00136         SNLineManager(Module *creator) : XLineManager(creator, "xlinemanager/snline", 'N') { }
00137 
00138         void OnMatch(User *u, XLine *x) anope_override
00139         {
00140                 this->Send(u, x);
00141         }
00142 
00143         void OnExpire(const XLine *x) anope_override
00144         {
00145                 Log(findbot(Config->OperServ), "expire/snline") << "SNLINE on \2" << x->Mask << "\2 has expired";
00146         }
00147 
00148         void Send(User *u, XLine *x) anope_override
00149         {
00150                 ircdproto->SendSGLine(u, x);
00151         }
00152 
00153         void SendDel(XLine *x) anope_override
00154         {
00155                 ircdproto->SendSGLineDel(x);
00156         }
00157 
00158         bool Check(User *u, const XLine *x) anope_override
00159         {
00160                 if (x->regex)
00161                         return x->regex->Matches(u->realname);
00162                 return Anope::Match(u->realname, x->Mask, false, true);
00163         }
00164 };
00165 
00166 class OperServCore : public Module
00167 {
00168         SGLineManager sglines;
00169         SQLineManager sqlines;
00170         SNLineManager snlines;
00171 
00172  public:
00173         OperServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
00174                 sglines(this), sqlines(this), snlines(this)
00175         {
00176                 this->SetAuthor("Anope");
00177 
00178                 if (!findbot(Config->OperServ))
00179                         throw ModuleException("No bot named " + Config->OperServ);
00180 
00181                 Implementation i[] = { I_OnBotPrivmsg, I_OnServerQuit, I_OnUserModeSet, I_OnUserModeUnset, I_OnUserConnect, I_OnUserNickChange, I_OnPreHelp };
00182                 ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
00183 
00184                 /* Yes, these are in this order for a reason. Most violent->least violent. */
00185                 XLineManager::RegisterXLineManager(&sglines);
00186                 XLineManager::RegisterXLineManager(&sqlines);
00187                 XLineManager::RegisterXLineManager(&snlines);
00188         }
00189 
00190         ~OperServCore()
00191         {
00192                 this->sglines.Clear();
00193                 this->sqlines.Clear();
00194                 this->snlines.Clear();
00195 
00196                 XLineManager::UnregisterXLineManager(&sglines);
00197                 XLineManager::UnregisterXLineManager(&sqlines);
00198                 XLineManager::UnregisterXLineManager(&snlines);
00199         }
00200 
00201         EventReturn OnBotPrivmsg(User *u, BotInfo *bi, Anope::string &message) anope_override
00202         {
00203                 if (Config->OSOpersOnly && !u->HasMode(UMODE_OPER) && bi->nick == Config->OperServ)
00204                 {
00205                         u->SendMessage(bi, ACCESS_DENIED);
00206                         Log(findbot(Config->OperServ), "bados") << "Denied access to " << Config->OperServ << " from " << u->GetMask() << " (non-oper)";
00207                         return EVENT_STOP;
00208                 }
00209 
00210                 return EVENT_CONTINUE;
00211         }
00212 
00213         void OnServerQuit(Server *server) anope_override
00214         {
00215                 if (server->HasFlag(SERVER_JUPED))
00216                         Log(server, "squit", findbot(Config->OperServ)) << "Received SQUIT for juped server " << server->GetName();
00217         }
00218 
00219         void OnUserModeSet(User *u, UserModeName Name) anope_override
00220         {
00221                 if (Name == UMODE_OPER)
00222                         Log(u, "oper", findbot(Config->OperServ)) << "is now an IRC operator.";
00223         }
00224 
00225         void OnUserModeUnset(User *u, UserModeName Name) anope_override
00226         {
00227                 if (Name == UMODE_OPER)
00228                         Log(u, "oper", findbot(Config->OperServ)) << "is no longer an IRC operator";
00229         }
00230 
00231         void OnUserConnect(dynamic_reference<User> &u, bool &exempt) anope_override
00232         {
00233                 if (u && !exempt)
00234                         XLineManager::CheckAll(u);
00235         }
00236 
00237         void OnUserNickChange(User *u, const Anope::string &oldnick) anope_override
00238         {
00239                 if (ircdproto->CanSQLine && !u->HasMode(UMODE_OPER))
00240                         this->sqlines.CheckAllXLines(u);
00241         }
00242 
00243         EventReturn OnCheckKick(User *u, ChannelInfo *ci, bool &kick) anope_override
00244         {
00245                 if (this->sqlines.CheckChannel(ci->c))
00246                         kick = true;
00247                 return EVENT_CONTINUE;
00248         }
00249 
00250         EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
00251         {
00252                 if (!params.empty() || source.c || source.service->nick != Config->OperServ)
00253                         return EVENT_CONTINUE;
00254                 source.Reply(_("%s commands:"), Config->OperServ.c_str());
00255                 return EVENT_CONTINUE;
00256         }
00257 };
00258 
00259 MODULE_INIT(OperServCore)
00260