diff options
-rw-r--r-- | data/operserv.example.conf | 6 | ||||
-rw-r--r-- | include/config.h | 2 | ||||
-rw-r--r-- | include/oper.h | 61 | ||||
-rw-r--r-- | modules/commands/os_akill.cpp | 28 | ||||
-rw-r--r-- | modules/commands/os_chankill.cpp | 3 | ||||
-rw-r--r-- | modules/commands/os_defcon.cpp | 29 | ||||
-rw-r--r-- | modules/commands/os_session.cpp | 4 | ||||
-rw-r--r-- | modules/commands/os_sxline.cpp | 90 | ||||
-rw-r--r-- | modules/database/db_old.cpp | 24 | ||||
-rw-r--r-- | modules/database/db_plain.cpp | 6 | ||||
-rw-r--r-- | modules/extra/m_dnsbl.cpp | 11 | ||||
-rw-r--r-- | modules/extra/m_proxyscan.cpp | 13 | ||||
-rw-r--r-- | modules/pseudoclients/operserv.cpp | 143 | ||||
-rw-r--r-- | src/config.cpp | 1 | ||||
-rw-r--r-- | src/operserv.cpp | 121 |
15 files changed, 274 insertions, 268 deletions
diff --git a/data/operserv.example.conf b/data/operserv.example.conf index 69467516c..ac038a58a 100644 --- a/data/operserv.example.conf +++ b/data/operserv.example.conf @@ -205,6 +205,12 @@ operserv addakiller = yes /* + * Adds akill IDs to akills. Akill IDs are given to users in their ban reason and can be used to easily view, + * modify, or remove an akill from the ID. + */ + akillids = yes + + /* * If set, only IRC Operators will be permitted to use OperServ, regardless of module-based command * access restrictions. * diff --git a/include/config.h b/include/config.h index e333a06fd..51fcfc424 100644 --- a/include/config.h +++ b/include/config.h @@ -611,6 +611,8 @@ class CoreExport ServerConfig bool WallExceptionExpire; /* Add the akillers nick to the akill reason */ bool AddAkiller; + /* Add akill ids to akill reason */ + bool AkillIds; /* Limit sessions */ bool LimitSessions; diff --git a/include/oper.h b/include/oper.h index fb046bdbe..1d4092b4a 100644 --- a/include/oper.h +++ b/include/oper.h @@ -21,11 +21,12 @@ class CoreExport XLine : public Serializable<XLine> time_t Created; time_t Expires; Anope::string Reason; - Anope::string Manager; + XLineManager *manager; + Anope::string UID; - XLine(const Anope::string &mask, const Anope::string &reason = ""); + XLine(const Anope::string &mask, const Anope::string &reason = "", const Anope::string &uid = ""); - XLine(const Anope::string &mask, const Anope::string &by, const time_t expires, const Anope::string &reason); + XLine(const Anope::string &mask, const Anope::string &by, const time_t expires, const Anope::string &reason, const Anope::string &uid); Anope::string GetNick() const; Anope::string GetUser() const; @@ -39,26 +40,13 @@ class CoreExport XLine : public Serializable<XLine> class CoreExport XLineManager : public Service<XLineManager> { char type; - protected: /* List of XLines in this XLineManager */ std::vector<XLine *> XLines; + static std::map<Anope::string, XLine *, std::less<ci::string> > XLinesByUID; public: /* List of XLine managers we check users against in XLineManager::CheckAll */ static std::list<XLineManager *> XLineManagers; - /** Constructor - */ - XLineManager(Module *creator, const Anope::string &name, char t); - - /** Destructor - */ - virtual ~XLineManager(); - - /** The type of xline provided by this service - * @return The type - */ - const char &Type(); - /** Register a XLineManager, places it in XLineManagers for use in XLineManager::CheckAll * It is important XLineManagers are registered in the proper order. Eg, if you had one akilling * clients and one handing them free olines, you would want the akilling one first. This way if a client @@ -78,6 +66,24 @@ class CoreExport XLineManager : public Service<XLineManager> */ static std::pair<XLineManager *, XLine *> CheckAll(User *u); + /** Generate a unique ID for this XLine + * @return A unique ID + */ + static Anope::string GenerateUID(); + + /** Constructor + */ + XLineManager(Module *creator, const Anope::string &name, char t); + + /** Destructor + */ + virtual ~XLineManager(); + + /** The type of xline provided by this service + * @return The type + */ + const char &Type(); + /** Get the number of XLines in this XLineManager * @return The number of XLines */ @@ -109,22 +115,6 @@ class CoreExport XLineManager : public Service<XLineManager> */ void Clear(); - /** Add an entry to this XLine Manager - * @param mask The mask of the XLine - * @param creator The creator of the XLine - * @param expires When this should expire - * @param reaosn The reason - * @return A pointer to the XLine - */ - virtual XLine *Add(const Anope::string &mask, const Anope::string &creator, time_t expires, const Anope::string &reason); - - private: - /** Delete an XLine, eg, remove it from the IRCd. - * @param x The xline - */ - virtual void Del(XLine *x); - - public: /** Checks if a mask can/should be added to the XLineManager * @param mask The mask * @param expires When the mask would expire @@ -164,6 +154,11 @@ class CoreExport XLineManager : public Service<XLineManager> * @param x The xline */ virtual void Send(User *u, XLine *x) = 0; + + /** Called to remove an XLine from the IRCd + * @param x The XLine + */ + virtual void SendDel(XLine *x) = 0; }; #endif // OPER_H diff --git a/modules/commands/os_akill.cpp b/modules/commands/os_akill.cpp index 99aa60089..3b82fb5fb 100644 --- a/modules/commands/os_akill.cpp +++ b/modules/commands/os_akill.cpp @@ -208,7 +208,14 @@ class CommandOSAKill : public Command if (Config->AddAkiller) reason = "[" + u->nick + "] " + reason; - XLine *x = akills->Add(mask, u->nick, expires, reason); + Anope::string id; + if (Config->AkillIds) + { + id = XLineManager::GenerateUID(); + reason = reason + " (ID: " + id + ")"; + } + + XLine *x = new XLine(mask, u->nick, expires, reason, id); EventReturn MOD_RESULT; FOREACH_RESULT(I_OnAddXLine, OnAddXLine(u, x, akills)); @@ -218,9 +225,13 @@ class CommandOSAKill : public Command return; } + akills->AddXLine(x); + if (Config->AkillOnAdd) + akills->Send(NULL, x); + source.Reply(_("\002%s\002 added to the AKILL list."), mask.c_str()); - Log(LOG_ADMIN, u, this) << "on " << mask << " (" << reason << ") expires in " << (expires ? duration(expires - Anope::CurTime) : "never") << " [affects " << affected << " user(s) (" << percent << "%)]"; + Log(LOG_ADMIN, u, this) << "on " << mask << " (" << x->Reason << ") expires in " << (expires ? duration(expires - Anope::CurTime) : "never") << " [affects " << affected << " user(s) (" << percent << "%)]"; if (readonly) source.Reply(READ_ONLY_MODE); @@ -266,8 +277,9 @@ class CommandOSAKill : public Command FOREACH_MOD(I_OnDelXLine, OnDelXLine(u, x, akills)); + source.Reply(_("\002%s\002 deleted from the AKILL list."), x->Mask.c_str()); AkillDelCallback::DoDel(source, x); - source.Reply(_("\002%s\002 deleted from the AKILL list."), mask.c_str()); + } if (readonly) @@ -299,7 +311,7 @@ class CommandOSAKill : public Command { XLine *x = akills->GetEntry(i); - if (mask.empty() || mask.equals_ci(x->Mask) || Anope::Match(x->Mask, mask)) + if (mask.empty() || mask.equals_ci(x->Mask) || mask == x->UID || Anope::Match(x->Mask, mask)) { if (!SentHeader) { @@ -344,7 +356,7 @@ class CommandOSAKill : public Command { XLine *x = akills->GetEntry(i); - if (mask.empty() || mask.equals_ci(x->Mask) || Anope::Match(x->Mask, mask)) + if (mask.empty() || mask.equals_ci(x->Mask) || mask == x->UID || Anope::Match(x->Mask, mask)) { if (!SentHeader) { @@ -377,9 +389,9 @@ class CommandOSAKill : public Command { this->SetDesc(_("Manipulate the AKILL list")); this->SetSyntax(_("ADD [+\037expiry\037] \037mask\037 \037reason\037")); - this->SetSyntax(_("DEL {\037mask\037 | \037entry-num\037 | \037list\037}")); - this->SetSyntax(_("LIST [\037mask\037 | \037list\037]")); - this->SetSyntax(_("VIEW [\037mask\037 | \037list\037]")); + this->SetSyntax(_("DEL {\037mask\037 | \037entry-num\037 | \037list\037 | \037id\037}")); + this->SetSyntax(_("LIST [\037mask\037 | \037list\037 | \037id\037]")); + this->SetSyntax(_("VIEW [\037mask\037 | \037list\037 | \037id\037]")); this->SetSyntax(_("CLEAR")); } diff --git a/modules/commands/os_chankill.cpp b/modules/commands/os_chankill.cpp index 53e7dfd9c..e6b69cb9f 100644 --- a/modules/commands/os_chankill.cpp +++ b/modules/commands/os_chankill.cpp @@ -80,7 +80,8 @@ class CommandOSChanKill : public Command if (uc->user->server == Me || uc->user->HasMode(UMODE_OPER)) continue; - akills->Add("*@" + uc->user->host, u->nick, expires, realreason); + XLine *x = new XLine("*@" + uc->user->host, u->nick, expires, realreason, XLineManager::GenerateUID()); + akills->AddXLine(x); akills->Check(uc->user); } diff --git a/modules/commands/os_defcon.cpp b/modules/commands/os_defcon.cpp index 4966f9e78..f97dfab92 100644 --- a/modules/commands/os_defcon.cpp +++ b/modules/commands/os_defcon.cpp @@ -424,9 +424,9 @@ class OSDefcon : public Module if (DConfig.Check(DEFCON_AKILL_NEW_CLIENTS) && akills) { Log(findbot(Config->OperServ), "operserv/defcon") << "DEFCON: adding akill for *@" << u->host; - XLine *x = akills->Add("*@" + u->host, Config->OperServ, Anope::CurTime + DConfig.akillexpire, DConfig.akillreason); - if (x) - x->By = Config->OperServ; + XLine *x = new XLine("*@" + u->host, Config->OperServ, Anope::CurTime + DConfig.akillexpire, DConfig.akillreason, XLineManager::GenerateUID()); + x->By = Config->OperServ; + akills->AddXLine(x); } if (DConfig.Check(DEFCON_NO_NEW_CLIENTS) || DConfig.Check(DEFCON_AKILL_NEW_CLIENTS)) @@ -518,9 +518,9 @@ class OSDefcon : public Module if (DConfig.Check(DEFCON_AKILL_NEW_CLIENTS) && akills) { Log(findbot(Config->OperServ), "operserv/defcon") << "DEFCON: adding akill for *@" << u->host; - XLine *x = akills->Add("*@" + u->host, Config->OperServ, Anope::CurTime + DConfig.akillexpire, DConfig.akillreason); - if (x) - x->By = Config->OperServ; + XLine x("*@" + u->host, Config->OperServ, Anope::CurTime + DConfig.akillexpire, DConfig.akillreason, XLineManager::GenerateUID()); + x.By = Config->OperServ; + akills->Send(NULL, &x); } if (DConfig.Check(DEFCON_NO_NEW_CLIENTS) || DConfig.Check(DEFCON_AKILL_NEW_CLIENTS)) { @@ -528,23 +528,15 @@ class OSDefcon : public Module return; } - if (!DConfig.sessionlimit) - return; - - if (DConfig.Check(DEFCON_AKILL_NEW_CLIENTS) && akills) - { - Log(findbot(Config->OperServ), "operserv/defcon") << "DEFCON: adding akill for *@" << u->host; - XLine *x = akills->Add("*@" + u->host, Config->OperServ, Anope::CurTime + DConfig.akillexpire, !DConfig.akillreason.empty() ? DConfig.akillreason : "DEFCON AKILL"); - if (x) - x->By = Config->OperServ; - } - if (DConfig.Check(DEFCON_NO_NEW_CLIENTS) || DConfig.Check(DEFCON_AKILL_NEW_CLIENTS)) { u->Kill(Config->OperServ, DConfig.akillreason); return; } + if (!DConfig.sessionlimit) + return; + Session *session = session_service->FindSession(u->host); Exception *exception = session_service->FindException(u); @@ -561,7 +553,8 @@ class OSDefcon : public Module ++session->hits; if (akills && Config->MaxSessionKill && session->hits >= Config->MaxSessionKill) { - akills->Add("*@" + u->host, Config->OperServ, Anope::CurTime + Config->SessionAutoKillExpiry, "Defcon session limit exceeded"); + XLine x("*@" + u->host, Config->OperServ, Anope::CurTime + Config->SessionAutoKillExpiry, "Defcon session limit exceeded", XLineManager::GenerateUID()); + akills->Send(NULL, &x); ircdproto->SendGlobops(findbot(Config->OperServ), "[DEFCON] Added a temporary AKILL for \2*@%s\2 due to excessive connections", u->host.c_str()); } } diff --git a/modules/commands/os_session.cpp b/modules/commands/os_session.cpp index a6a2d2396..edaf841d5 100644 --- a/modules/commands/os_session.cpp +++ b/modules/commands/os_session.cpp @@ -679,7 +679,9 @@ class OSSession : public Module if (Config->MaxSessionKill && session->hits >= Config->MaxSessionKill && akills) { const Anope::string &akillmask = "*@" + u->host; - akills->Add(akillmask, Config->OperServ, Anope::CurTime + Config->SessionAutoKillExpiry, "Session limit exceeded"); + XLine *x = new XLine(akillmask, Config->OperServ, Anope::CurTime + Config->SessionAutoKillExpiry, "Session limit exceeded", XLineManager::GenerateUID()); + akills->AddXLine(x); + akills->Send(NULL, x); if (bi) ircdproto->SendGlobops(bi, "Added a temporary AKILL for \2%s\2 due to excessive connections", akillmask.c_str()); } diff --git a/modules/commands/os_sxline.cpp b/modules/commands/os_sxline.cpp index 80ad9db8c..56444383d 100644 --- a/modules/commands/os_sxline.cpp +++ b/modules/commands/os_sxline.cpp @@ -205,7 +205,7 @@ class CommandOSSXLineBase : public Command { XLine *x = this->xlm()->GetEntry(i); - if (mask.empty() || mask.equals_ci(x->Mask) || Anope::Match(x->Mask, mask)) + if (mask.empty() || mask.equals_ci(x->Mask) || mask == x->UID || Anope::Match(x->Mask, mask)) { if (!SentHeader) { @@ -249,7 +249,7 @@ class CommandOSSXLineBase : public Command { XLine *x = this->xlm()->GetEntry(i); - if (mask.empty() || mask.equals_ci(x->Mask) || Anope::Match(x->Mask, mask)) + if (mask.empty() || mask.equals_ci(x->Mask) || mask == x->UID || Anope::Match(x->Mask, mask)) { if (!SentHeader) { @@ -278,14 +278,9 @@ class CommandOSSXLineBase : public Command return; } public: - CommandOSSXLineBase(Module *creator, const Anope::string &cmd) : Command(creator, cmd, 1, 3) + CommandOSSXLineBase(Module *creator, const Anope::string &cmd) : Command(creator, cmd, 1, 4) { this->SetDesc(Anope::printf(_("Manipulate the %s list"), cmd.c_str())); - this->SetSyntax(_("ADD [+\037expiry\037] \037mask\037:\037reason\037")); - this->SetSyntax(_("DEL {\037mask\037 | \037entry-num\037 | \037list\037}")); - this->SetSyntax(_("LIST [\037mask\037 | \037list\037]")); - this->SetSyntax(_("VIEW [\037mask\037 | \037list\037]")); - this->SetSyntax(_("CLEAR")); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) @@ -410,7 +405,14 @@ class CommandOSSNLine : public CommandOSSXLineBase if (Config->AddAkiller) reason = "[" + u->nick + "] " + reason; - XLine *x = this->xlm()->Add(mask, u->nick, expires, reason); + Anope::string id; + if (Config->AkillIds) + { + id = XLineManager::GenerateUID(); + reason = reason + " (ID: " + id + ")"; + } + + XLine *x = new XLine(mask, u->nick, expires, reason, id); EventReturn MOD_RESULT; FOREACH_RESULT(I_OnAddXLine, OnAddXLine(u, x, this->xlm())); @@ -420,6 +422,21 @@ class CommandOSSNLine : public CommandOSSXLineBase return; } + this->xlm()->AddXLine(x); + if (Config->KillonSNline && !ircd->sglineenforce) + { + Anope::string rreason = "G-Lined: " + reason; + + for (Anope::insensitive_map<User *>::const_iterator it = UserListByNick.begin(); it != UserListByNick.end();) + { + User *user = it->second; + ++it; + + if (!user->HasMode(UMODE_OPER) && user->server != Me && Anope::Match(user->realname, x->Mask)) + user->Kill(Config->ServerName, rreason); + } + } + source.Reply(_("\002%s\002 added to the %s list."), mask.c_str(), this->name.c_str()); Log(LOG_ADMIN, u, this) << "on " << mask << " (" << reason << ") expires in " << (expires ? duration(expires - Anope::CurTime) : "never") << " [affects " << affected << " user(s) (" << percent << "%)]"; @@ -438,6 +455,11 @@ class CommandOSSNLine : public CommandOSSXLineBase public: CommandOSSNLine(Module *creator) : CommandOSSXLineBase(creator, "operserv/snline"), snlines("xlinemanager/snline") { + this->SetSyntax(_("ADD [+\037expiry\037] \037mask\037:\037reason\037")); + this->SetSyntax(_("DEL {\037mask\037 | \037entry-num\037 | \037list\037 | \037id\037}")); + this->SetSyntax(_("LIST [\037mask\037 | \037list\037 | \037id\037]")); + this->SetSyntax(_("VIEW [\037mask\037 | \037list\037 | \037id\037]")); + this->SetSyntax(_("CLEAR")); } bool OnHelp(CommandSource &source, const Anope::string &subcommand) @@ -494,7 +516,7 @@ class CommandOSSQLine : public CommandOSSXLineBase void OnAdd(CommandSource &source, const std::vector<Anope::string> ¶ms) { - if (!this->xlm() ||! ircd->sqline) + if (!this->xlm() || !ircd->sqline) { source.Reply(_("Your IRCd does not support SQLINE")); return; @@ -563,7 +585,10 @@ class CommandOSSQLine : public CommandOSSXLineBase return; } - XLine *x = this->sqlines->Add(mask, u->nick, expires, reason); + Anope::string id = XLineManager::GenerateUID(); + reason = reason + " (ID: " + id + ")"; + + XLine *x = new XLine(mask, u->nick, expires, reason, id); EventReturn MOD_RESULT; FOREACH_RESULT(I_OnAddXLine, OnAddXLine(u, x, this->xlm())); @@ -573,6 +598,44 @@ class CommandOSSQLine : public CommandOSSXLineBase return; } + this->xlm()->AddXLine(x); + if (Config->KillonSQline) + { + Anope::string rreason = "Q-Lined: " + reason; + + if (mask[0] == '#') + { + for (channel_map::const_iterator cit = ChannelList.begin(), cit_end = ChannelList.end(); cit != cit_end; ++cit) + { + Channel *c = cit->second; + + if (!Anope::Match(c->name, mask)) + continue; + for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ) + { + UserContainer *uc = *it; + ++it; + + if (uc->user->HasMode(UMODE_OPER) || uc->user->server == Me) + continue; + c->Kick(NULL, uc->user, "%s", reason.c_str()); + } + } + } + else + { + for (Anope::insensitive_map<User *>::const_iterator it = UserListByNick.begin(); it != UserListByNick.end();) + { + User *user = it->second; + ++it; + + if (!user->HasMode(UMODE_OPER) && user->server != Me && Anope::Match(user->nick, x->Mask)) + user->Kill(Config->ServerName, rreason); + } + } + } + this->xlm()->Send(NULL, x); + source.Reply(_("\002%s\002 added to the SQLINE list."), mask.c_str()); Log(LOG_ADMIN, u, this) << "on " << mask << " (" << reason << ") expires in " << (expires ? duration(expires - Anope::CurTime) : "never") << " [affects " << affected << " user(s) (" << percent << "%)]"; @@ -591,6 +654,11 @@ class CommandOSSQLine : public CommandOSSXLineBase public: CommandOSSQLine(Module *creator) : CommandOSSXLineBase(creator, "operserv/sqline"), sqlines("xlinemanager/sqline") { + this->SetSyntax(_("ADD [+\037expiry\037] \037mask\037 \037reason\037")); + this->SetSyntax(_("DEL {\037mask\037 | \037entry-num\037 | \037list\037 | \037id\037}")); + this->SetSyntax(_("LIST [\037mask\037 | \037list\037 | \037id\037]")); + this->SetSyntax(_("VIEW [\037mask\037 | \037list\037 | \037id\037]")); + this->SetSyntax(_("CLEAR")); } bool OnHelp(CommandSource &source, const Anope::string &subcommand) diff --git a/modules/database/db_old.cpp b/modules/database/db_old.cpp index 55956da78..440713a6e 100644 --- a/modules/database/db_old.cpp +++ b/modules/database/db_old.cpp @@ -920,9 +920,9 @@ static void LoadOper() if (!akill) continue; - XLine *x = akill->Add(user + "@" + host, by, expires, reason); - if (x) - x->Created = seton; + XLine *x = new XLine(user + "@" + host, by, expires, reason, XLineManager::GenerateUID()); + x->Created = seton; + akill->AddXLine(x); } read_int16(&capacity, f); // SNLines @@ -940,9 +940,9 @@ static void LoadOper() if (!snline) continue; - XLine *x = snline->Add(mask, by, expires, reason); - if (x) - x->Created = seton; + XLine *x = new XLine(mask, by, expires, reason, XLineManager::GenerateUID()); + x->Created = seton; + snline->AddXLine(x); } read_int16(&capacity, f); // SQLines @@ -960,9 +960,9 @@ static void LoadOper() if (!sqline) continue; - XLine *x = sqline->Add(mask, by, expires, reason); - if (x) - x->Created = seton; + XLine *x = new XLine(mask, by, expires, reason, XLineManager::GenerateUID()); + x->Created = seton; + sqline->AddXLine(x); } read_int16(&capacity, f); // SZLines @@ -980,9 +980,9 @@ static void LoadOper() if (!szline) continue; - XLine *x = szline->Add(mask, by, expires, reason); - if (x) - x->Created = seton; + XLine *x = new XLine(mask, by, expires, reason, XLineManager::GenerateUID()); + x->Created = seton; + szline->AddXLine(x); } close_db(f); diff --git a/modules/database/db_plain.cpp b/modules/database/db_plain.cpp index 4ac109018..3605c0b9d 100644 --- a/modules/database/db_plain.cpp +++ b/modules/database/db_plain.cpp @@ -548,9 +548,9 @@ static void LoadOperInfo(const std::vector<Anope::string> ¶ms) time_t expires = params[6].is_pos_number_only() ? convertTo<time_t>(params[6]) : 0; Anope::string reason = params[7]; - XLine *x = xl->Add(mask, by, expires, reason); - if (x) - x->Created = seton; + XLine *x = new XLine(mask, by, expires, reason, XLineManager::GenerateUID()); + x->Created = seton; + xl->AddXLine(x); break; } } diff --git a/modules/extra/m_dnsbl.cpp b/modules/extra/m_dnsbl.cpp index 894eebb8a..4be489aa7 100644 --- a/modules/extra/m_dnsbl.cpp +++ b/modules/extra/m_dnsbl.cpp @@ -63,17 +63,16 @@ class DNSBLResolver : public DNSRequest BotInfo *operserv = findbot(Config->OperServ); Log(operserv) << "DNSBL: " << user->GetMask() << " appears in " << this->blacklist.name; + XLine *x = new XLine("*@" + user->host, Config->OperServ, Anope::CurTime + this->blacklist.bantime, reason, XLineManager::GenerateUID()); if (this->add_to_akill && akills) { - XLine *x = akills->Add("*@" + user->host, Config->OperServ, Anope::CurTime + this->blacklist.bantime, reason); - /* If AkillOnAdd is disabled send it anyway, noone wants bots around... */ - if (!Config->AkillOnAdd) - akills->Send(NULL, x); + akills->AddXLine(x); + akills->Send(NULL, x); } else { - XLine xline("*@" + user->host, Config->OperServ, Anope::CurTime + this->blacklist.bantime, reason); - ircdproto->SendAkill(NULL, &xline); + ircdproto->SendAkill(NULL, x); + delete x; } } }; diff --git a/modules/extra/m_proxyscan.cpp b/modules/extra/m_proxyscan.cpp index 1964e6bf0..685d984b0 100644 --- a/modules/extra/m_proxyscan.cpp +++ b/modules/extra/m_proxyscan.cpp @@ -86,20 +86,19 @@ class ProxyConnect : public ConnectionSocket reason = reason.replace_all_cs("%p", stringify(this->conaddr.port())); Log(findbot(Config->OperServ)) << "PROXYSCAN: Open " << this->GetType() << " proxy found on " << this->conaddr.addr() << ":" << this->conaddr.port() << " (" << reason << ")"; + XLine *x = new XLine("*@" + this->conaddr.addr(), Config->OperServ, Anope::CurTime + this->proxy.duration, reason, XLineManager::GenerateUID()); if (add_to_akill && akills) { - XLine *x = akills->Add("*@" + this->conaddr.addr(), Config->OperServ, Anope::CurTime + this->proxy.duration, reason); - /* If AkillOnAdd is disabled send it anyway, noone wants bots around... */ - if (!Config->AkillOnAdd) - akills->Send(NULL, x); + akills->AddXLine(x); + akills->Send(NULL, x); } else { - XLine xline("*@" + this->conaddr.addr(), Config->OperServ, Anope::CurTime + this->proxy.duration, reason); if (ircd->szline) - ircdproto->SendSZLine(NULL, &xline); + ircdproto->SendSZLine(NULL, x); else - ircdproto->SendAkill(NULL, &xline); + ircdproto->SendAkill(NULL, x); + delete x; } } }; diff --git a/modules/pseudoclients/operserv.cpp b/modules/pseudoclients/operserv.cpp index 6dfacd19f..d29c2c66e 100644 --- a/modules/pseudoclients/operserv.cpp +++ b/modules/pseudoclients/operserv.cpp @@ -20,19 +20,20 @@ class SGLineManager : public XLineManager public: SGLineManager(Module *creator) : XLineManager(creator, "xlinemanager/sgline", 'G') { } - XLine *Add(const Anope::string &mask, const Anope::string &creator, time_t expires, const Anope::string &reason) + void OnMatch(User *u, XLine *x) { - XLine *x = new XLine(mask, creator, expires, reason); - - this->AddXLine(x); - - if (UplinkSock && Config->AkillOnAdd) - this->Send(NULL, x); - - return x; + if (u) + u->Kill(Config->OperServ, x->Reason); + this->Send(u, x); } - void Del(XLine *x) + void OnExpire(XLine *x) + { + if (Config->WallAkillExpire) + ircdproto->SendGlobops(OperServ, "AKILL on %s has expired", x->Mask.c_str()); + } + + void Send(User *u, XLine *x) { try { @@ -41,28 +42,15 @@ class SGLineManager : public XLineManager else if (x->GetUser() != "*") throw SocketException("Can not ZLine a username"); x->GetIP(); - ircdproto->SendSZLineDel(x); + ircdproto->SendSZLine(u, x); } catch (const SocketException &) { - ircdproto->SendAkillDel(x); + ircdproto->SendAkill(u, x); } } - void OnMatch(User *u, XLine *x) - { - if (u) - u->Kill(Config->OperServ, x->Reason); - this->Send(u, x); - } - - void OnExpire(XLine *x) - { - if (Config->WallAkillExpire) - ircdproto->SendGlobops(OperServ, "AKILL on %s has expired", x->Mask.c_str()); - } - - void Send(User *u, XLine *x) + void SendDel(XLine *x) { try { @@ -71,11 +59,11 @@ class SGLineManager : public XLineManager else if (x->GetUser() != "*") throw SocketException("Can not ZLine a username"); x->GetIP(); - ircdproto->SendSZLine(u, x); + ircdproto->SendSZLineDel(x); } catch (const SocketException &) { - ircdproto->SendAkill(u, x); + ircdproto->SendAkillDel(x); } } }; @@ -85,59 +73,6 @@ class SQLineManager : public XLineManager public: SQLineManager(Module *creator) : XLineManager(creator, "xlinemanager/sqline", 'Q') { } - XLine *Add(const Anope::string &mask, const Anope::string &creator, time_t expires, const Anope::string &reason) - { - XLine *x = new XLine(mask, creator, expires, reason); - - this->AddXLine(x); - - if (Config->KillonSQline) - { - Anope::string rreason = "Q-Lined: " + reason; - - if (mask[0] == '#') - { - for (channel_map::const_iterator cit = ChannelList.begin(), cit_end = ChannelList.end(); cit != cit_end; ++cit) - { - Channel *c = cit->second; - - if (!Anope::Match(c->name, mask)) - continue; - for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ) - { - UserContainer *uc = *it; - ++it; - - if (uc->user->HasMode(UMODE_OPER) || uc->user->server == Me) - continue; - c->Kick(NULL, uc->user, "%s", reason.c_str()); - } - } - } - else - { - for (Anope::insensitive_map<User *>::const_iterator it = UserListByNick.begin(); it != UserListByNick.end();) - { - User *user = it->second; - ++it; - - if (!user->HasMode(UMODE_OPER) && user->server != Me && Anope::Match(user->nick, x->Mask)) - user->Kill(Config->ServerName, rreason); - } - } - } - - if (UplinkSock) - this->Send(NULL, x); - - return x; - } - - void Del(XLine *x) - { - ircdproto->SendSQLineDel(x); - } - void OnMatch(User *u, XLine *x) { if (u) @@ -160,6 +95,11 @@ class SQLineManager : public XLineManager ircdproto->SendSQLine(u, x); } + void SendDel(XLine *x) + { + ircdproto->SendSQLineDel(x); + } + bool CheckChannel(Channel *c) { if (ircd->chansqline) @@ -175,34 +115,6 @@ class SNLineManager : public XLineManager public: SNLineManager(Module *creator) : XLineManager(creator, "xlinemanager/snline", 'N') { } - XLine *Add(const Anope::string &mask, const Anope::string &creator, time_t expires, const Anope::string &reason) - { - XLine *x = new XLine(mask, creator, expires, reason); - - this->AddXLine(x); - - if (Config->KillonSNline && !ircd->sglineenforce) - { - Anope::string rreason = "G-Lined: " + reason; - - for (Anope::insensitive_map<User *>::const_iterator it = UserListByNick.begin(); it != UserListByNick.end();) - { - User *user = it->second; - ++it; - - if (!user->HasMode(UMODE_OPER) && user->server != Me && Anope::Match(user->realname, x->Mask)) - user->Kill(Config->ServerName, rreason); - } - } - - return x; - } - - void Del(XLine *x) - { - ircdproto->SendSGLineDel(x); - } - void OnMatch(User *u, XLine *x) { if (u) @@ -224,18 +136,21 @@ class SNLineManager : public XLineManager ircdproto->SendSGLine(u, x); } + void SendDel(XLine *x) + { + ircdproto->SendSGLineDel(x); + } + XLine *Check(User *u) { - for (unsigned i = this->XLines.size(); i > 0; --i) + for (unsigned i = this->GetList().size(); i > 0; --i) { - XLine *x = this->XLines[i - 1]; + XLine *x = this->GetList()[i - 1]; if (x->Expires && x->Expires < Anope::CurTime) { this->OnExpire(x); - this->Del(x); - delete x; - this->XLines.erase(XLines.begin() + i - 1); + this->DelXLine(x); continue; } diff --git a/src/config.cpp b/src/config.cpp index f9139bf7a..bbfb6890d 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -1265,6 +1265,7 @@ ConfigItems::ConfigItems(ServerConfig *conf) {"operserv", "maxsessionkill", "0", new ValueContainerUInt(&conf->MaxSessionKill), DT_UINTEGER, NoValidation}, {"operserv", "sessionautokillexpiry", "0", new ValueContainerTime(&conf->SessionAutoKillExpiry), DT_TIME, NoValidation}, {"operserv", "addakiller", "no", new ValueContainerBool(&conf->AddAkiller), DT_BOOLEAN, NoValidation}, + {"operserv", "akillids", "no", new ValueContainerBool(&conf->AkillIds), DT_BOOLEAN, NoValidation}, {"operserv", "opersonly", "no", new ValueContainerBool(&conf->OSOpersOnly), DT_BOOLEAN, NoValidation}, {"global", "name", "", new ValueContainerString(&conf->Global), DT_STRING, NoValidation}, {"global", "globaloncycle", "no", new ValueContainerBool(&conf->GlobalOnCycle), DT_BOOLEAN, NoValidation}, diff --git a/src/operserv.cpp b/src/operserv.cpp index b0db3aee1..05d27d6ca 100644 --- a/src/operserv.cpp +++ b/src/operserv.cpp @@ -15,17 +15,20 @@ /* List of XLine managers we check users against in XLineManager::CheckAll */ std::list<XLineManager *> XLineManager::XLineManagers; +std::map<Anope::string, XLine *, std::less<ci::string> > XLineManager::XLinesByUID; XLine::XLine() { } -XLine::XLine(const Anope::string &mask, const Anope::string &reason) : Mask(mask), Created(0), Expires(0), Reason(reason) +XLine::XLine(const Anope::string &mask, const Anope::string &reason, const Anope::string &uid) : Mask(mask), Created(0), Expires(0), Reason(reason), UID(uid) { + manager = NULL; } -XLine::XLine(const Anope::string &mask, const Anope::string &by, const time_t expires, const Anope::string &reason) : Mask(mask), By(by), Created(Anope::CurTime), Expires(expires), Reason(reason) +XLine::XLine(const Anope::string &mask, const Anope::string &by, const time_t expires, const Anope::string &reason, const Anope::string &uid) : Mask(mask), By(by), Created(Anope::CurTime), Expires(expires), Reason(reason), UID(uid) { + manager = NULL; } Anope::string XLine::GetNick() const @@ -79,7 +82,9 @@ SerializableBase::serialized_data XLine::serialize() data["created"] << this->Created; data["expires"] << this->Expires; data["reason"] << this->Reason; - data["manager"] << this->Manager; + data["uid"] << this->UID; + if (this->manager) + data["manager"] << this->manager->name; return data; } @@ -97,38 +102,18 @@ void XLine::unserialize(SerializableBase::serialized_data &data) data["created"] >> xl->Created; data["expires"] >> xl->Expires; data["reason"] >> xl->Reason; + data["uid"] >> xl->UID; + xl->manager = xlm; xlm->AddXLine(xl); } -/** Constructor - */ -XLineManager::XLineManager(Module *creator, const Anope::string &xname, char t) : Service<XLineManager>(creator, xname), type(t) -{ -} - -/** Destructor - * Clears all XLines in this XLineManager - */ -XLineManager::~XLineManager() -{ - this->Clear(); -} - -/** The type of xline provided by this service - * @return The type +/** Register a XLineManager, places it in XLineManagers for use in XLineManager::CheckAll + * It is important XLineManagers are registered in the proper order. Eg, if you had one akilling + * clients and one handing them free olines, you would want the akilling one first. This way if a client + * matches an entry on both of the XLineManagers, they would be akilled. + * @param xlm THe XLineManager */ -const char &XLineManager::Type() -{ - return this->type; -} - - /** Register a XLineManager, places it in XLineManagers for use in XLineManager::CheckAll - * It is important XLineManagers are registered in the proper order. Eg, if you had one akilling - * clients and one handing them free olines, you would want the akilling one first. This way if a client - * matches an entry on both of the XLineManagers, they would be akilled. - * @param xlm THe XLineManager - */ void XLineManager::RegisterXLineManager(XLineManager *xlm) { XLineManagers.push_back(xlm); @@ -173,6 +158,43 @@ std::pair<XLineManager *, XLine *> XLineManager::CheckAll(User *u) return ret; } +Anope::string XLineManager::GenerateUID() +{ + Anope::string id; + for (int i = 0; i < 10; ++i) + { + char c; + do + c = getrandom8(); + while (!isupper(c) && !isdigit(c)); + id += c; + } + + return id; +} + +/** Constructor + */ +XLineManager::XLineManager(Module *creator, const Anope::string &xname, char t) : Service<XLineManager>(creator, xname), type(t) +{ +} + +/** Destructor + * Clears all XLines in this XLineManager + */ +XLineManager::~XLineManager() +{ + this->Clear(); +} + +/** The type of xline provided by this service + * @return The type + */ +const char &XLineManager::Type() +{ + return this->type; +} + /** Get the number of XLines in this XLineManager * @return The number of XLines */ @@ -194,7 +216,9 @@ const std::vector<XLine *> &XLineManager::GetList() const */ void XLineManager::AddXLine(XLine *x) { - x->Manager = this->name; + x->manager = this; + if (!x->UID.empty()) + XLinesByUID[x->UID] = x; this->XLines.push_back(x); } @@ -206,9 +230,12 @@ bool XLineManager::DelXLine(XLine *x) { std::vector<XLine *>::iterator it = std::find(this->XLines.begin(), this->XLines.end(), x); + if (!x->UID.empty()) + XLinesByUID.erase(x->UID); + if (it != this->XLines.end()) { - this->Del(x); + this->SendDel(x); delete x; this->XLines.erase(it); @@ -236,29 +263,14 @@ XLine *XLineManager::GetEntry(unsigned index) void XLineManager::Clear() { for (unsigned i = 0; i < this->XLines.size(); ++i) + { + if (!this->XLines[i]->UID.empty()) + XLinesByUID.erase(this->XLines[i]->UID); delete this->XLines[i]; + } this->XLines.clear(); } -/** Add an entry to this XLine Manager - * @param mask The mask of the XLine - * @param creator The creator of the XLine - * @param expires When this should expire - * @param reaosn The reason - * @return A pointer to the XLine - */ -XLine *XLineManager::Add(const Anope::string &mask, const Anope::string &creator, time_t expires, const Anope::string &reason) -{ - return NULL; -} - -/** Delete an XLine, eg, remove it from the IRCd. - * @param x The xline - */ -void XLineManager::Del(XLine *x) -{ -} - /** Checks if a mask can/should be added to the XLineManager * @param mask The mask * @param expires When the mask would expire @@ -315,6 +327,9 @@ std::pair<int, XLine *> XLineManager::CanAdd(const Anope::string &mask, time_t e */ XLine *XLineManager::HasEntry(const Anope::string &mask) { + std::map<Anope::string, XLine *, std::less<ci::string> >::iterator it = XLinesByUID.find(mask); + if (it != XLinesByUID.end() && (it->second->manager == NULL || it->second->manager == this)) + return it->second; for (unsigned i = 0, end = this->XLines.size(); i < end; ++i) { XLine *x = this->XLines[i]; @@ -339,9 +354,7 @@ XLine *XLineManager::Check(User *u) if (x->Expires && x->Expires < Anope::CurTime) { this->OnExpire(x); - this->Del(x); - delete x; - this->XLines.erase(XLines.begin() + i - 1); + this->DelXLine(x); continue; } |