anope

- supernets anope source code & configuration
git clone git://git.acid.vegas/anope.git
Log | Files | Refs | Archive | README

operserv.cpp (7335B)

      1 /* OperServ core functions
      2  *
      3  * (C) 2003-2022 Anope Team
      4  * Contact us at team@anope.org
      5  *
      6  * Please read COPYING and README for further details.
      7  *
      8  * Based on the original code of Epona by Lara.
      9  * Based on the original code of Services by Andy Church.
     10  */
     11 
     12 #include "module.h"
     13 
     14 class SGLineManager : public XLineManager
     15 {
     16  public:
     17 	SGLineManager(Module *creator) : XLineManager(creator, "xlinemanager/sgline", 'G') { }
     18 
     19 	void OnMatch(User *u, XLine *x) anope_override
     20 	{
     21 		this->Send(u, x);
     22 	}
     23 
     24 	void OnExpire(const XLine *x) anope_override
     25 	{
     26 		Log(Config->GetClient("OperServ"), "expire/akill") << "AKILL on \002" << x->mask << "\002 has expired";
     27 	}
     28 
     29 	void Send(User *u, XLine *x) anope_override
     30 	{
     31 		IRCD->SendAkill(u, x);
     32 	}
     33 
     34 	void SendDel(XLine *x) anope_override
     35 	{
     36 		IRCD->SendAkillDel(x);
     37 	}
     38 
     39 	bool Check(User *u, const XLine *x) anope_override
     40 	{
     41 		if (x->regex)
     42 		{
     43 			Anope::string uh = u->GetIdent() + "@" + u->host, nuhr = u->nick + "!" + uh + "#" + u->realname;
     44 			return x->regex->Matches(uh) || x->regex->Matches(nuhr);
     45 		}
     46 
     47 		if (!x->GetNick().empty() && !Anope::Match(u->nick, x->GetNick()))
     48 			return false;
     49 
     50 		if (!x->GetUser().empty() && !Anope::Match(u->GetIdent(), x->GetUser()))
     51 			return false;
     52 
     53 		if (!x->GetReal().empty() && !Anope::Match(u->realname, x->GetReal()))
     54 			return false;
     55 
     56 		if (x->c && x->c->match(u->ip))
     57 			return true;
     58 
     59 		if (x->GetHost().empty() || Anope::Match(u->host, x->GetHost()) || Anope::Match(u->ip.addr(), x->GetHost()))
     60 			return true;
     61 
     62 		return false;
     63 	}
     64 };
     65 
     66 class SQLineManager : public XLineManager
     67 {
     68 	ServiceReference<NickServService> nickserv;
     69 
     70  public:
     71 	SQLineManager(Module *creator) : XLineManager(creator, "xlinemanager/sqline", 'Q'), nickserv("NickServService", "NickServ") { }
     72 
     73 	void OnMatch(User *u, XLine *x) anope_override
     74 	{
     75 		this->Send(u, x);
     76 	}
     77 
     78 	void OnExpire(const XLine *x) anope_override
     79 	{
     80 		Log(Config->GetClient("OperServ"), "expire/sqline") << "SQLINE on \002" << x->mask << "\002 has expired";
     81 	}
     82 
     83 	void Send(User *u, XLine *x) anope_override
     84 	{
     85 		if (!IRCD->CanSQLine)
     86 		{
     87 			if (!u)
     88 				;
     89 			else if (nickserv)
     90 				nickserv->Collide(u, NULL);
     91 			else
     92 				u->Kill(Config->GetClient("OperServ"), "Q-Lined: " + x->reason);
     93 		}
     94 		else if (x->IsRegex())
     95 		{
     96 			if (u)
     97 				u->Kill(Config->GetClient("OperServ"), "Q-Lined: " + x->reason);
     98 		}
     99 		else if (x->mask[0] != '#' || IRCD->CanSQLineChannel)
    100 		{
    101 			IRCD->SendSQLine(u, x);
    102 			/* If it is an oper, assume they're walking it, otherwise kill for good measure */
    103 			if (u && !u->HasMode("OPER"))
    104 				u->Kill(Config->GetClient("OperServ"), "Q-Lined: " + x->reason);
    105 		}
    106 	}
    107 
    108 	void SendDel(XLine *x) anope_override
    109 	{
    110 		if (!IRCD->CanSQLine || x->IsRegex())
    111 			;
    112 		else if (x->mask[0] != '#' || IRCD->CanSQLineChannel)
    113 			IRCD->SendSQLineDel(x);
    114 	}
    115 
    116 	bool Check(User *u, const XLine *x) anope_override
    117 	{
    118 		if (x->regex)
    119 			return x->regex->Matches(u->nick);
    120 		return Anope::Match(u->nick, x->mask);
    121 	}
    122 
    123 	XLine *CheckChannel(Channel *c)
    124 	{
    125 		for (std::vector<XLine *>::const_iterator it = this->GetList().begin(), it_end = this->GetList().end(); it != it_end; ++it)
    126 		{
    127 			XLine *x = *it;
    128 
    129 			if (x->regex)
    130 			{
    131 				if (x->regex->Matches(c->name))
    132 					return x;
    133 			}
    134 			else
    135 			{
    136 				if (x->mask.empty() || x->mask[0] != '#')
    137 					continue;
    138 
    139 				if (Anope::Match(c->name, x->mask, false, true))
    140 					return x;
    141 			}
    142 		}
    143 		return NULL;
    144 	}
    145 };
    146 
    147 class SNLineManager : public XLineManager
    148 {
    149  public:
    150 	SNLineManager(Module *creator) : XLineManager(creator, "xlinemanager/snline", 'N') { }
    151 
    152 	void OnMatch(User *u, XLine *x) anope_override
    153 	{
    154 		this->Send(u, x);
    155 	}
    156 
    157 	void OnExpire(const XLine *x) anope_override
    158 	{
    159 		Log(Config->GetClient("OperServ"), "expire/snline") << "SNLINE on \002" << x->mask << "\002 has expired";
    160 	}
    161 
    162 	void Send(User *u, XLine *x) anope_override
    163 	{
    164 		if (IRCD->CanSNLine && !x->IsRegex())
    165 			IRCD->SendSGLine(u, x);
    166 
    167 		if (u)
    168 			u->Kill(Config->GetClient("OperServ"), "SNLined: " + x->reason);
    169 	}
    170 
    171 	void SendDel(XLine *x) anope_override
    172 	{
    173 		if (IRCD->CanSNLine && !x->IsRegex())
    174 			IRCD->SendSGLineDel(x);
    175 	}
    176 
    177 	bool Check(User *u, const XLine *x) anope_override
    178 	{
    179 		if (x->regex)
    180 			return x->regex->Matches(u->realname);
    181 		return Anope::Match(u->realname, x->mask, false, true);
    182 	}
    183 };
    184 
    185 class OperServCore : public Module
    186 {
    187 	Reference<BotInfo> OperServ;
    188 	SGLineManager sglines;
    189 	SQLineManager sqlines;
    190 	SNLineManager snlines;
    191 
    192  public:
    193 	OperServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR),
    194 		sglines(this), sqlines(this), snlines(this)
    195 	{
    196 
    197 		/* Yes, these are in this order for a reason. Most violent->least violent. */
    198 		XLineManager::RegisterXLineManager(&sglines);
    199 		XLineManager::RegisterXLineManager(&sqlines);
    200 		XLineManager::RegisterXLineManager(&snlines);
    201 	}
    202 
    203 	~OperServCore()
    204 	{
    205 		this->sglines.Clear();
    206 		this->sqlines.Clear();
    207 		this->snlines.Clear();
    208 
    209 		XLineManager::UnregisterXLineManager(&sglines);
    210 		XLineManager::UnregisterXLineManager(&sqlines);
    211 		XLineManager::UnregisterXLineManager(&snlines);
    212 	}
    213 
    214 	void OnReload(Configuration::Conf *conf) anope_override
    215 	{
    216 		const Anope::string &osnick = conf->GetModule(this)->Get<const Anope::string>("client");
    217 
    218 		if (osnick.empty())
    219 			throw ConfigException(this->name + ": <client> must be defined");
    220 
    221 		BotInfo *bi = BotInfo::Find(osnick, true);
    222 		if (!bi)
    223 			throw ConfigException(this->name + ": no bot named " + osnick);
    224 
    225 		OperServ = bi;
    226 	}
    227 
    228 	EventReturn OnBotPrivmsg(User *u, BotInfo *bi, Anope::string &message) anope_override
    229 	{
    230 		if (bi == OperServ && !u->HasMode("OPER") && Config->GetModule(this)->Get<bool>("opersonly"))
    231 		{
    232 			u->SendMessage(bi, ACCESS_DENIED);
    233 			Log(bi, "bados") << "Denied access to " << bi->nick << " from " << u->GetMask() << " (non-oper)";
    234 			return EVENT_STOP;
    235 		}
    236 
    237 		return EVENT_CONTINUE;
    238 	}
    239 
    240 	void OnServerQuit(Server *server) anope_override
    241 	{
    242 		if (server->IsJuped())
    243 			Log(server, "squit", OperServ) << "Received SQUIT for juped server " << server->GetName();
    244 	}
    245 
    246 	void OnUserModeSet(const MessageSource &setter, User *u, const Anope::string &mname) anope_override
    247 	{
    248 		if (mname == "OPER")
    249 			Log(u, "oper", OperServ) << "is now an IRC operator.";
    250 	}
    251 
    252 	void OnUserModeUnset(const MessageSource &setter, User *u, const Anope::string &mname) anope_override
    253 	{
    254 		if (mname == "OPER")
    255 			Log(u, "oper", OperServ) << "is no longer an IRC operator";
    256 	}
    257 
    258 	void OnUserConnect(User *u, bool &exempt) anope_override
    259 	{
    260 		if (!u->Quitting() && !exempt)
    261 			XLineManager::CheckAll(u);
    262 	}
    263 
    264 	void OnUserNickChange(User *u, const Anope::string &oldnick) anope_override
    265 	{
    266 		if (!u->HasMode("OPER"))
    267 			this->sqlines.CheckAllXLines(u);
    268 	}
    269 
    270 	EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) anope_override
    271 	{
    272 		XLine *x = this->sqlines.CheckChannel(c);
    273 		if (x)
    274 		{
    275 			this->sqlines.OnMatch(u, x);
    276 			reason = x->reason;
    277 			return EVENT_STOP;
    278 		}
    279 
    280 		return EVENT_CONTINUE;
    281 	}
    282 
    283 	EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
    284 	{
    285 		if (!params.empty() || source.c || source.service != *OperServ)
    286 			return EVENT_CONTINUE;
    287 		source.Reply(_("%s commands:"), OperServ->nick.c_str());
    288 		return EVENT_CONTINUE;
    289 	}
    290 
    291 	void OnLog(Log *l) anope_override
    292 	{
    293 		if (l->type == LOG_SERVER)
    294 			l->bi = OperServ;
    295 	}
    296 };
    297 
    298 MODULE_INIT(OperServCore)