summaryrefslogtreecommitdiff
path: root/modules/extra
diff options
context:
space:
mode:
Diffstat (limited to 'modules/extra')
-rw-r--r--modules/extra/cs_appendtopic.cpp14
-rw-r--r--modules/extra/cs_enforce.cpp10
-rw-r--r--modules/extra/cs_entrymsg.cpp12
-rw-r--r--modules/extra/cs_set_misc.cpp16
-rw-r--r--modules/extra/cs_tban.cpp12
-rw-r--r--modules/extra/db_mysql.cpp87
-rw-r--r--modules/extra/hs_request.cpp47
-rw-r--r--modules/extra/m_alias.cpp9
-rw-r--r--modules/extra/m_dnsbl.cpp44
-rw-r--r--modules/extra/m_helpchan.cpp9
-rw-r--r--modules/extra/m_ldap.cpp4
-rw-r--r--modules/extra/m_ldap_authentication.cpp19
-rw-r--r--modules/extra/m_ldap_oper.cpp4
-rw-r--r--modules/extra/m_mysql.cpp4
-rw-r--r--modules/extra/m_xmlrpc.cpp6
-rw-r--r--modules/extra/m_xmlrpc_main.cpp7
-rw-r--r--modules/extra/ns_maxemail.cpp10
-rw-r--r--modules/extra/ns_set_misc.cpp13
-rw-r--r--modules/extra/os_defcon.cpp693
19 files changed, 873 insertions, 147 deletions
diff --git a/modules/extra/cs_appendtopic.cpp b/modules/extra/cs_appendtopic.cpp
index b02717d92..dc3b40288 100644
--- a/modules/extra/cs_appendtopic.cpp
+++ b/modules/extra/cs_appendtopic.cpp
@@ -17,8 +17,7 @@
/*************************************************************************/
#include "module.h"
-
-#define AUTHOR "SGR"
+#include "chanserv.h"
/* ------------------------------------------------------------
* Name: cs_appendtopic
@@ -110,12 +109,15 @@ class CSAppendTopic : public Module
public:
CSAppendTopic(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
{
- me = this;
-
- this->SetAuthor(AUTHOR);
+ this->SetAuthor("SGR");
this->SetType(SUPPORTED);
- this->AddCommand(ChanServ, &commandcsappendtopic);
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ me = this;
+
+ this->AddCommand(chanserv->Bot(), &commandcsappendtopic);
}
};
diff --git a/modules/extra/cs_enforce.cpp b/modules/extra/cs_enforce.cpp
index 3a8e11735..6e39f33f3 100644
--- a/modules/extra/cs_enforce.cpp
+++ b/modules/extra/cs_enforce.cpp
@@ -14,6 +14,7 @@
*/
#include "module.h"
+#include "chanserv.h"
static Module *me;
@@ -217,12 +218,15 @@ class CSEnforce : public Module
public:
CSEnforce(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
{
- me = this;
-
this->SetAuthor("Anope");
this->SetType(SUPPORTED);
- this->AddCommand(ChanServ, &commandcsenforce);
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ me = this;
+
+ this->AddCommand(chanserv->Bot(), &commandcsenforce);
}
};
diff --git a/modules/extra/cs_entrymsg.cpp b/modules/extra/cs_entrymsg.cpp
index 649fd69f8..f424baede 100644
--- a/modules/extra/cs_entrymsg.cpp
+++ b/modules/extra/cs_entrymsg.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
struct EntryMsg
{
@@ -162,13 +163,16 @@ class CSEntryMessage : public Module
{
this->SetAuthor("Anope");
this->SetType(CORE);
+
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
Implementation i[] = { I_OnJoinChannel, I_OnReload, I_OnDatabaseReadMetadata, I_OnDatabaseWriteMetadata };
ModuleManager::Attach(i, this, 4);
- this->AddCommand(ChanServ, &commandentrymsg);
+ this->AddCommand(chanserv->Bot(), &commandentrymsg);
- this->OnReload(false);
+ this->OnReload();
}
void OnJoinChannel(User *u, Channel *c)
@@ -179,11 +183,11 @@ class CSEntryMessage : public Module
if (c->ci->GetExtRegular("cs_entrymsg", messages))
for (unsigned i = 0; i < messages.size(); ++i)
- u->SendMessage(whosends(c->ci), "[%s] %s", c->ci->name.c_str(), messages[i].message.c_str());
+ u->SendMessage(c->ci->WhoSends(), "[%s] %s", c->ci->name.c_str(), messages[i].message.c_str());
}
}
- void OnReload(bool)
+ void OnReload()
{
ConfigReader config;
EntryMsg::MaxEntries = config.ReadInteger("cs_entrymsg", "maxentries", "5", 0, true);
diff --git a/modules/extra/cs_set_misc.cpp b/modules/extra/cs_set_misc.cpp
index cb654a9a1..4bd7a772a 100644
--- a/modules/extra/cs_set_misc.cpp
+++ b/modules/extra/cs_set_misc.cpp
@@ -11,6 +11,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSSetMisc : public Command
{
@@ -77,8 +78,8 @@ class CSSetMisc : public Module
if (Commands.empty())
return;
- Command *set = FindCommand(ChanServ, "SET");
- Command *saset = FindCommand(ChanServ, "SASET");
+ Command *set = FindCommand(chanserv->Bot(), "SET");
+ Command *saset = FindCommand(chanserv->Bot(), "SASET");
if (!set && !saset)
return;
@@ -114,10 +115,13 @@ class CSSetMisc : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
Implementation i[] = { I_OnReload, I_OnChanInfo, I_OnDatabaseWriteMetadata, I_OnDatabaseReadMetadata };
ModuleManager::Attach(i, this, 4);
- OnReload(true);
+ OnReload();
}
~CSSetMisc()
@@ -125,12 +129,12 @@ class CSSetMisc : public Module
RemoveAll();
}
- void OnReload(bool)
+ void OnReload()
{
RemoveAll();
- Command *set = FindCommand(ChanServ, "SET");
- Command *saset = FindCommand(ChanServ, "SASET");
+ Command *set = FindCommand(chanserv->Bot(), "SET");
+ Command *saset = FindCommand(chanserv->Bot(), "SASET");
if (!set && !saset)
return;
diff --git a/modules/extra/cs_tban.cpp b/modules/extra/cs_tban.cpp
index e3470504d..04d608246 100644
--- a/modules/extra/cs_tban.cpp
+++ b/modules/extra/cs_tban.cpp
@@ -16,6 +16,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
static Module *me;
@@ -110,12 +111,15 @@ class CSTBan : public Module
public:
CSTBan(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
{
- me = this;
-
- this->AddCommand(ChanServ, &commandcstban);
-
this->SetAuthor("Anope");
this->SetType(SUPPORTED);
+
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ me = this;
+
+ this->AddCommand(chanserv->Bot(), &commandcstban);
}
};
diff --git a/modules/extra/db_mysql.cpp b/modules/extra/db_mysql.cpp
index 9a2c44d47..30a71c809 100644
--- a/modules/extra/db_mysql.cpp
+++ b/modules/extra/db_mysql.cpp
@@ -1,5 +1,7 @@
#include "module.h"
+#include "operserv.h"
#include "sql.h"
+#include "os_session.h"
static Anope::string ToString(const std::vector<Anope::string> &strings)
{
@@ -89,6 +91,7 @@ class DBMySQL : public Module
service_reference<SQLProvider> SQL;
public:
+ service_reference<SessionService> SessionInterface;
time_t lastwarn;
bool ro;
@@ -99,7 +102,8 @@ class DBMySQL : public Module
if (readonly && this->ro)
{
readonly = this->ro = false;
- ircdproto->SendGlobops(OperServ, "Found SQL again, going out of readonly mode...");
+ if (operserv)
+ ircdproto->SendGlobops(operserv->Bot(), "Found SQL again, going out of readonly mode...");
}
SQL->Run(&sqlinterface, query);
@@ -108,7 +112,8 @@ class DBMySQL : public Module
{
if (Anope::CurTime - Config->UpdateTimeout > lastwarn)
{
- ircdproto->SendGlobops(OperServ, "Unable to locate SQL reference, is m_mysql loaded? Going to readonly...");
+ if (operserv)
+ ircdproto->SendGlobops(operserv->Bot(), "Unable to locate SQL reference, is m_mysql loaded? Going to readonly...");
readonly = this->ro = true;
this->lastwarn = Anope::CurTime;
}
@@ -120,7 +125,7 @@ class DBMySQL : public Module
return SQL ? SQL->Escape(query) : query;
}
- DBMySQL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), sqlinterface(this), SQL("mysql/main")
+ DBMySQL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), sqlinterface(this), SQL("mysql/main"), SessionInterface("session")
{
me = this;
@@ -134,7 +139,8 @@ class DBMySQL : public Module
};
ModuleManager::Attach(i, this, 2);
- this->AddCommand(OperServ, &commandsqlsync);
+ if (operserv)
+ this->AddCommand(operserv->Bot(), &commandsqlsync);
if (uplink_server)
OnServerConnect();
@@ -542,12 +548,9 @@ class DBMySQL : public Module
time_t seton = r.Get(i, "seton").is_pos_number_only() ? convertTo<time_t>(r.Get(i, "seton")) : Anope::CurTime;
time_t expires = r.Get(i, "expires").is_pos_number_only() ? convertTo<time_t>(r.Get(i, "expires")) : Anope::CurTime;
- XLine *x = SGLine->Add(NULL, NULL, user + "@" + host, expires, reason);
+ XLine *x = SGLine->Add(user + "@" + host, by, expires, reason);
if (x)
- {
- x->By = by;
x->Created = seton;
- }
}
}
@@ -562,16 +565,13 @@ class DBMySQL : public Module
XLine *x = NULL;
if (SNLine && r.Get(i, "type").equals_cs("SNLINE"))
- x = SNLine->Add(NULL, NULL, mask, expires, reason);
+ x = SNLine->Add(mask, by, expires, reason);
else if (SQLine && r.Get(i, "type").equals_cs("SQLINE"))
- x = SQLine->Add(NULL, NULL, mask, expires, reason);
+ x = SQLine->Add(mask, by, expires, reason);
else if (SZLine && r.Get(i, "type").equals_cs("SZLINE"))
- x = SZLine->Add(NULL, NULL, mask, expires, reason);
+ x = SZLine->Add(mask, by, expires, reason);
if (x)
- {
- x->By = by;
x->Created = seton;
- }
}
r = SQL->RunQuery("SELECT * FROM `anope_os_exceptions`");
@@ -583,7 +583,16 @@ class DBMySQL : public Module
Anope::string reason = r.Get(i, "reason");
time_t expires = convertTo<time_t>(r.Get(i, "expires"));
- exception_add(NULL, mask, limit, reason, creator, expires);
+ if (SessionInterface)
+ {
+ Exception *e = new Exception();
+ e->mask = mask;
+ e->limit = limit;
+ e->who = creator;
+ e->reason = reason;
+ e->time = expires;
+ SessionInterface->AddException(e);
+ }
}
r = SQL->RunQuery("SELECT * FROM `anope_extra`");
@@ -661,7 +670,7 @@ class DBMySQL : public Module
BotInfo *service = command->service;
ChannelInfo *ci = source.ci;
- if (service == NickServ)
+ if (service->nick == Config->s_NickServ)
{
if (u->Account() && ((command->name.equals_ci("SET") && !params.empty()) || (command->name.equals_ci("SASET") && u->HasCommand("nickserv/saset") && params.size() > 1)))
{
@@ -691,7 +700,7 @@ class DBMySQL : public Module
}
}
}
- else if (service == ChanServ)
+ else if (service->nick == Config->s_ChanServ)
{
if (command->name.equals_ci("SET") && u->Account() && params.size() > 1)
{
@@ -721,7 +730,7 @@ class DBMySQL : public Module
}
}
}
- else if (service == BotServ)
+ else if (service->nick == Config->s_BotServ)
{
if (command->name.equals_ci("KICK") && params.size() > 2)
{
@@ -773,7 +782,7 @@ class DBMySQL : public Module
}
}
}
- else if (service == MemoServ)
+ else if (service->nick == Config->s_MemoServ)
{
if (command->name.equals_ci("IGNORE") && params.size() > 0)
{
@@ -1049,18 +1058,12 @@ class DBMySQL : public Module
this->RunQuery(query);
}
- void OnMemoSend(User *, NickCore *nc, Memo *m)
- {
- this->RunQuery("INSERT INTO `anope_ms_info` (receiver, flags, time, sender, text, serv) VALUES('" +
- this->Escape(nc->display) + "', '" + ToString(m->ToString()) + "', " + stringify(m->time) + ", '" +
- this->Escape(m->sender) + "', '" + this->Escape(m->text) + "', 'NICK')");
- }
-
- void OnMemoSend(User *, ChannelInfo *ci, Memo *m)
+ void OnMemoSend(const Anope::string &source, const Anope::string &target, MemoInfo *mi, Memo *m)
{
+ const Anope::string &mtype = (!target.empty() && target[0] == '#' ? "CHAN" : "NICK");
this->RunQuery("INSERT INTO `anope_ms_info` (receiver, flags, time, sender, text, serv) VALUES('" +
- this->Escape(ci->name) + "', '" + ToString(m->ToString()) + "', " + stringify(m->time) + ", '" +
- this->Escape(m->sender) + "', '" + this->Escape(m->text) + "', 'CHAN')");
+ this->Escape(target) + "', '" + ToString(m->ToString()) + "', " + stringify(m->time) + ", '" +
+ this->Escape(source) + "', '" + this->Escape(m->text) + "', '" + mtype + "')");
}
void OnMemoDel(const NickCore *nc, MemoInfo *mi, Memo *m)
@@ -1079,7 +1082,7 @@ class DBMySQL : public Module
this->RunQuery("DELETE FROM `anope_ms_info` WHERE `receiver` = '" + this->Escape(ci->name) + "'");
}
- EventReturn OnAddAkill(User *, XLine *ak)
+ EventReturn OnAddAkill(XLine *ak)
{
this->RunQuery("INSERT INTO `anope_os_akills` (user, host, xby, reason, seton, expire) VALUES('" +
this->Escape(ak->GetUser()) + "', '" + this->Escape(ak->GetHost()) + "', '" + this->Escape(ak->By) + "', '" +
@@ -1095,7 +1098,7 @@ class DBMySQL : public Module
this->RunQuery("TRUNCATE TABLE `anope_os_akills`");
}
- EventReturn OnExceptionAdd(User *, Exception *ex)
+ EventReturn OnExceptionAdd(Exception *ex)
{
this->RunQuery("INSERT INTO `anope_os_exceptions` (mask, slimit, who, reason, time, expires) VALUES('" +
this->Escape(ex->mask) + "', " + stringify(ex->limit) + ", '" + this->Escape(ex->who) + "', '" + this->Escape(ex->reason) + "', " +
@@ -1108,7 +1111,7 @@ class DBMySQL : public Module
this->RunQuery("DELETE FROM `anope_os_exceptions` WHERE `mask` = '" + this->Escape(ex->mask) + "'");
}
- EventReturn OnAddXLine(User *, XLine *x, XLineType Type)
+ EventReturn OnAddXLine(XLine *x, XLineType Type)
{
this->RunQuery(Anope::string("INSERT INTO `anope_os_xlines` (type, mask, xby, reason, seton, expire) VALUES('") +
(Type == X_SNLINE ? "SNLINE" : (Type == X_SQLINE ? "SQLINE" : "SZLINE")) + "', '" +
@@ -1216,7 +1219,7 @@ static void SaveDatabases()
{
Memo *m = nc->memos.memos[j];
- me->OnMemoSend(NULL, nc, m);
+ me->OnMemoSend(m->sender, nc->display, &nc->memos, m);
}
}
@@ -1267,35 +1270,35 @@ static void SaveDatabases()
{
Memo *m = ci->memos.memos[j];
- me->OnMemoSend(NULL, ci, m);
+ me->OnMemoSend(m->sender, ci->name, &ci->memos, m);
}
}
if (SGLine)
for (unsigned i = 0, end = SGLine->GetCount(); i < end; ++i)
- me->OnAddAkill(NULL, SGLine->GetEntry(i));
+ me->OnAddAkill(SGLine->GetEntry(i));
if (SZLine)
for (unsigned i = 0, end = SZLine->GetCount(); i < end; ++i)
- me->OnAddXLine(NULL, SZLine->GetEntry(i), X_SZLINE);
+ me->OnAddXLine(SZLine->GetEntry(i), X_SZLINE);
if (SQLine)
for (unsigned i = 0, end = SQLine->GetCount(); i < end; ++i)
- me->OnAddXLine(NULL, SQLine->GetEntry(i), X_SQLINE);
+ me->OnAddXLine(SQLine->GetEntry(i), X_SQLINE);
if (SNLine)
for (unsigned i = 0, end = SNLine->GetCount(); i < end; ++i)
- me->OnAddXLine(NULL, SNLine->GetEntry(i), X_SNLINE);
+ me->OnAddXLine(SNLine->GetEntry(i), X_SNLINE);
- for (unsigned i = 0, end = exceptions.size(); i < end; ++i)
- me->OnExceptionAdd(NULL, exceptions[i]);
+ if (me->SessionInterface)
+ for (SessionService::ExceptionVector::iterator it = me->SessionInterface->GetExceptions().begin(); it != me->SessionInterface->GetExceptions().end(); ++it)
+ me->OnExceptionAdd(*it);
}
CommandReturn CommandSQLSync::Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
- User *u = source.u;
SaveDatabases();
- u->SendMessage(OperServ, _("Updating MySQL."));
+ source.Reply(_("Updating MySQL."));
return MOD_CONT;
}
diff --git a/modules/extra/hs_request.cpp b/modules/extra/hs_request.cpp
index 4978035d3..f208d72b3 100644
--- a/modules/extra/hs_request.cpp
+++ b/modules/extra/hs_request.cpp
@@ -16,6 +16,8 @@
*/
#include "module.h"
+#include "hostserv.h"
+#include "memoserv.h"
static bool HSRequestMemoUser = false;
static bool HSRequestMemoOper = false;
@@ -152,8 +154,8 @@ class CommandHSActivate : public Command
na->hostinfo.SetVhost(it->second->ident, it->second->host, u->nick, it->second->time);
FOREACH_MOD(I_OnSetVhost, OnSetVhost(na));
- if (HSRequestMemoUser)
- memo_send(source, na->nick, _("[auto memo] Your requested vHost has been approved."), 2);
+ if (HSRequestMemoUser && memoserv)
+ memoserv->Send(Config->s_HostServ, na->nick, _("[auto memo] Your requested vHost has been approved."), true);
me->SendMessage(source, _("vHost for %s has been activated"), na->nick.c_str());
Log(LOG_COMMAND, u, this, NULL) << "for " << na->nick << " for vhost " << (!it->second->ident.empty() ? it->second->ident + "@" : "") << it->second->host;
@@ -207,15 +209,15 @@ class CommandHSReject : public Command
delete it->second;
Requests.erase(it);
- if (HSRequestMemoUser)
+ if (HSRequestMemoUser && memoserv)
{
- char message[BUFSIZE];
+ Anope::string message;
if (!reason.empty())
- snprintf(message, sizeof(message), _("[auto memo] Your requested vHost has been rejected. Reason: %s"), reason.c_str());
+ message = Anope::printf(_("[auto memo] Your requested vHost has been rejected. Reason: %s"), reason.c_str());
else
- snprintf(message, sizeof(message), "%s", _("[auto memo] Your requested vHost has been rejected."));
+ message = _("[auto memo] Your requested vHost has been rejected.");
- memo_send(source, nick, message, 2);
+ memoserv->Send(Config->s_HostServ, nick, message, true);
}
me->SendMessage(source, _("vHost for %s has been rejected"), nick.c_str());
@@ -312,18 +314,21 @@ class HSRequest : public Module
{
me = this;
- this->AddCommand(HostServ, &commandhsrequest);
- this->AddCommand(HostServ, &commandhsactive);
- this->AddCommand(HostServ, &commandhsreject);
- this->AddCommand(HostServ, &commandhswaiting);
+ if (!hostserv)
+ throw ModuleException("HostServ is not loaded!");
+
+ this->AddCommand(hostserv->Bot(), &commandhsrequest);
+ this->AddCommand(hostserv->Bot(), &commandhsactive);
+ this->AddCommand(hostserv->Bot(), &commandhsreject);
+ this->AddCommand(hostserv->Bot(), &commandhswaiting);
this->SetAuthor("Anope");
this->SetType(SUPPORTED);
- this->OnReload(false);
-
Implementation i[] = { I_OnPreCommand, I_OnDatabaseRead, I_OnDatabaseWrite, I_OnReload };
ModuleManager::Attach(i, this, 4);
+
+ this->OnReload();
}
~HSRequest()
@@ -339,7 +344,7 @@ class HSRequest : public Module
EventReturn OnPreCommand(CommandSource &source, Command *command, const std::vector<Anope::string> &params)
{
BotInfo *service = source.owner;
- if (service == HostServ)
+ if (service->nick == Config->s_HostServ)
{
if (command->name.equals_ci("LIST"))
{
@@ -348,7 +353,7 @@ class HSRequest : public Module
if (!key.empty() && key.equals_ci("+req"))
{
std::vector<Anope::string> emptyParams;
- Command *c = FindCommand(HostServ, "WAITING");
+ Command *c = FindCommand(hostserv->Bot(), "WAITING");
if (!c)
throw CoreException("No waiting command?");
c->Execute(source, emptyParams);
@@ -356,7 +361,7 @@ class HSRequest : public Module
}
}
}
- else if (service == NickServ)
+ else if (service->nick == Config->s_NickServ)
{
if (command->name.equals_ci("DROP"))
{
@@ -402,7 +407,7 @@ class HSRequest : public Module
}
}
- void OnReload(bool)
+ void OnReload()
{
ConfigReader config;
HSRequestMemoUser = config.ReadFlag("hs_request", "memouser", "no", 0);
@@ -422,7 +427,7 @@ void req_send_memos(CommandSource &source, const Anope::string &vIdent, const An
else
host = vHost;
- if (HSRequestMemoOper == 1)
+ if (HSRequestMemoOper == 1 && memoserv)
for (unsigned i = 0; i < Config->Opers.size(); ++i)
{
Oper *o = Config->Opers[i];
@@ -431,9 +436,9 @@ void req_send_memos(CommandSource &source, const Anope::string &vIdent, const An
if (!na)
continue;
- char message[BUFSIZE];
- snprintf(message, sizeof(message), _("[auto memo] vHost \002%s\002 has been requested."), host.c_str());
- memo_send(source, na->nick, message, 2);
+ Anope::string message = Anope::printf(_("[auto memo] vHost \002%s\002 has been requested by %s."), host.c_str(), source.u->GetMask().c_str());
+
+ memoserv->Send(Config->s_HostServ, na->nick, message, true);
}
}
diff --git a/modules/extra/m_alias.cpp b/modules/extra/m_alias.cpp
index c5f52bef2..025a53df0 100644
--- a/modules/extra/m_alias.cpp
+++ b/modules/extra/m_alias.cpp
@@ -6,6 +6,7 @@
*/
#include "module.h"
+#include "chanserv.h"
struct CommandAlias
{
@@ -26,10 +27,10 @@ class ModuleAlias : public Module
Implementation i[] = { I_OnReload, I_OnPreCommandRun, I_OnBotFantasy };
ModuleManager::Attach(i, this, 3);
- OnReload(false);
+ OnReload();
}
- void OnReload(bool)
+ void OnReload()
{
ConfigReader config;
@@ -102,10 +103,10 @@ class ModuleAlias : public Module
BotInfo *target = findbot(alias.target_client);
if (!target)
- target = ChanServ;
+ target = chanserv->Bot();
Anope::string full_message = alias.target_command;
- if (target == ChanServ || target == BotServ)
+ if (target == chanserv->Bot() || target->nick == Config->s_BotServ)
{
Command *target_c = FindCommand(target, alias.target_command);
if (target_c && !target_c->HasFlag(CFLAG_STRIP_CHANNEL))
diff --git a/modules/extra/m_dnsbl.cpp b/modules/extra/m_dnsbl.cpp
index 5c88e75b5..f2572e694 100644
--- a/modules/extra/m_dnsbl.cpp
+++ b/modules/extra/m_dnsbl.cpp
@@ -6,10 +6,11 @@
*/
#include "module.h"
+#include "operserv.h"
struct FakeAkill : public Command
{
- FakeAkill() : Command("AKILL", 0, 0) { this->service = OperServ; }
+ FakeAkill() : Command("AKILL", 0, 0) { this->service = findbot(Config->s_OperServ); }
CommandReturn Execute(CommandSource &, const std::vector<Anope::string> &) { return MOD_CONT; }
} fake_akill;
@@ -61,18 +62,18 @@ class DNSBLResolver : public DNSRequest
reason = reason.replace_all_cs("%N", Config->NetworkName);
XLine *x = NULL;
- if (this->add_to_akill && SGLine && (x = SGLine->Add(NULL, NULL, Anope::string("*@") + user->host, Anope::CurTime + this->blacklist.bantime, reason)))
+ if (this->add_to_akill && SGLine && (x = SGLine->Add(Anope::string("*@") + user->host, Config->s_OperServ, Anope::CurTime + this->blacklist.bantime, reason)))
{
- Log(LOG_COMMAND, OperServ, &fake_akill) << "for " << user->GetMask() << " (Listed in " << this->blacklist.name << ")";
+ Log(LOG_COMMAND, operserv->Bot(), &fake_akill) << "for " << user->GetMask() << " (Listed in " << this->blacklist.name << ")";
/* If AkillOnAdd is disabled send it anyway, noone wants bots around... */
if (!Config->AkillOnAdd)
- ircdproto->SendAkill(*user, x);
+ ircdproto->SendAkill(user, x);
}
else
{
- Log(OperServ) << "DNSBL: " << user->GetMask() << " appears in " << this->blacklist.name;
- XLine xline(Anope::string("*@") + user->host, OperServ ? OperServ->nick : "OperServ", Anope::CurTime + this->blacklist.bantime, reason);
- ircdproto->SendAkill(*user, &xline);
+ Log(operserv->Bot()) << "DNSBL: " << user->GetMask() << " appears in " << this->blacklist.name;
+ XLine xline(Anope::string("*@") + user->host, Config->s_OperServ, Anope::CurTime + this->blacklist.bantime, reason);
+ ircdproto->SendAkill(user, &xline);
}
}
};
@@ -90,13 +91,13 @@ class ModuleDNSBL : public Module
this->SetAuthor("Anope");
this->SetType(SUPPORTED);
- OnReload(false);
-
- Implementation i[] = { I_OnReload, I_OnPreUserConnect };
+ Implementation i[] = { I_OnReload, I_OnUserConnect };
ModuleManager::Attach(i, this, 2);
+
+ OnReload();
}
- void OnReload(bool)
+ void OnReload()
{
ConfigReader config;
@@ -127,17 +128,18 @@ class ModuleDNSBL : public Module
}
}
- EventReturn OnPreUserConnect(User *u)
+ void OnUserConnect(dynamic_reference<User> &user, bool &exempt)
{
- if (!this->check_on_connect && !Me->IsSynced())
- return EVENT_CONTINUE;
- if (!this->check_on_netburst && !u->server->IsSynced())
- return EVENT_CONTINUE;
+ if (exempt || !user || (!this->check_on_connect && !Me->IsSynced()))
+ return;
+
+ if (!this->check_on_netburst && !user->server->IsSynced())
+ return;
/* At this time we only support IPv4 */
- if (u->ip.sa.sa_family != AF_INET)
- return EVENT_CONTINUE;
+ if (user->ip.sa.sa_family != AF_INET)
+ return;
- unsigned long ip = u->ip.sa4.sin_addr.s_addr;
+ unsigned long ip = user->ip.sa4.sin_addr.s_addr;
unsigned long reverse_ip = ((ip & 0xFF) << 24) | ((ip & 0xFF00) << 8) | ((ip & 0xFF0000) >> 8) | ((ip & 0xFF000000) >> 24);
sockaddrs user_ip;
@@ -151,7 +153,7 @@ class ModuleDNSBL : public Module
try
{
Anope::string dnsbl_host = user_ip.addr() + "." + b.name;
- DNSBLResolver *res = new DNSBLResolver(this, u, b, dnsbl_host, this->add_to_akill);
+ DNSBLResolver *res = new DNSBLResolver(this, user, b, dnsbl_host, this->add_to_akill);
res->Process();
}
catch (const SocketException &ex)
@@ -160,7 +162,7 @@ class ModuleDNSBL : public Module
}
}
- return EVENT_CONTINUE;
+ return;
}
};
diff --git a/modules/extra/m_helpchan.cpp b/modules/extra/m_helpchan.cpp
index 028e5e332..90a33ca79 100644
--- a/modules/extra/m_helpchan.cpp
+++ b/modules/extra/m_helpchan.cpp
@@ -6,6 +6,7 @@
*/
#include "module.h"
+#include "operserv.h"
class HelpChannel : public Module
{
@@ -20,23 +21,23 @@ class HelpChannel : public Module
Implementation i[] = { I_OnChannelModeSet, I_OnReload };
ModuleManager::Attach(i, this, 2);
- OnReload(true);
+ OnReload();
}
EventReturn OnChannelModeSet(Channel *c, ChannelModeName Name, const Anope::string &param)
{
- if (Name == CMODE_OP && c && c->ci && c->name.equals_ci(this->HelpChan))
+ if (Name == CMODE_OP && operserv && c && c->ci && c->name.equals_ci(this->HelpChan))
{
User *u = finduser(param);
if (u && check_access(u, c->ci, CA_OPDEOPME))
- u->SetMode(OperServ, UMODE_HELPOP);
+ u->SetMode(operserv->Bot(), UMODE_HELPOP);
}
return EVENT_CONTINUE;
}
- void OnReload(bool)
+ void OnReload()
{
ConfigReader config;
diff --git a/modules/extra/m_ldap.cpp b/modules/extra/m_ldap.cpp
index c7f0914a0..157bc70ac 100644
--- a/modules/extra/m_ldap.cpp
+++ b/modules/extra/m_ldap.cpp
@@ -210,7 +210,7 @@ class ModuleLDAP : public Module, public Pipe
Implementation i[] = { I_OnReload, I_OnModuleUnload };
ModuleManager::Attach(i, this, 2);
- OnReload(true);
+ OnReload();
}
~ModuleLDAP()
@@ -225,7 +225,7 @@ class ModuleLDAP : public Module, public Pipe
LDAPServices.clear();
}
- void OnReload(bool startup)
+ void OnReload()
{
ConfigReader config;
int i, num;
diff --git a/modules/extra/m_ldap_authentication.cpp b/modules/extra/m_ldap_authentication.cpp
index fa60247e5..f2caac63d 100644
--- a/modules/extra/m_ldap_authentication.cpp
+++ b/modules/extra/m_ldap_authentication.cpp
@@ -1,4 +1,5 @@
#include "module.h"
+#include "nickserv.h"
#include "ldap.h"
static Anope::string email_attribute;
@@ -44,8 +45,8 @@ class IdentifyInterface : public LDAPInterface
return;
}
- User *u = *ii->user;
- Command *c = *ii->command;
+ User *u = ii->user;
+ Command *c = ii->command;
u->Extend("m_ldap_authentication_authenticated");
@@ -56,7 +57,7 @@ class IdentifyInterface : public LDAPInterface
if (Config->NSAddAccessOnReg)
na->nc->AddAccess(create_mask(u));
- u->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), na->nick.c_str());
+ u->SendMessage(nickserv->Bot(), _("Your account \002%s\002 has been successfully created."), na->nick.c_str());
}
enc_encrypt(ii->pass, na->nc->pass);
@@ -83,8 +84,8 @@ class IdentifyInterface : public LDAPInterface
return;
}
- User *u = *ii->user;
- Command *c = *ii->command;
+ User *u = ii->user;
+ Command *c = ii->command;
u->Extend("m_ldap_authentication_error");
@@ -128,7 +129,7 @@ class OnIdentifyInterface : public LDAPInterface
if (!email.equals_ci(u->Account()->email))
{
u->Account()->email = email;
- u->SendMessage(NickServ, _("Your email has been updated to \002%s\002"), email.c_str());
+ u->SendMessage(nickserv->Bot(), _("Your email has been updated to \002%s\002"), email.c_str());
Log() << "m_ldap_authentication: Updated email address for " << u->nick << " (" << u->Account()->display << ") to " << email;
}
}
@@ -166,10 +167,10 @@ class NSIdentifyLDAP : public Module
ModuleManager::Attach(i, this, 4);
ModuleManager::SetPriority(this, PRIORITY_FIRST);
- OnReload(false);
+ OnReload();
}
- void OnReload(bool)
+ void OnReload()
{
ConfigReader config;
@@ -182,7 +183,7 @@ class NSIdentifyLDAP : public Module
EventReturn OnPreCommand(CommandSource &source, Command *command, const std::vector<Anope::string> &params)
{
- if (this->disable_register && command->service == NickServ && command->name == "REGISTER")
+ if (this->disable_register && nickserv && command->service == nickserv->Bot() && command->name == "REGISTER")
{
source.Reply(_(this->disable_reason.c_str()));
return EVENT_STOP;
diff --git a/modules/extra/m_ldap_oper.cpp b/modules/extra/m_ldap_oper.cpp
index b8a1d5f51..8010031cb 100644
--- a/modules/extra/m_ldap_oper.cpp
+++ b/modules/extra/m_ldap_oper.cpp
@@ -93,10 +93,10 @@ class LDAPOper : public Module
Implementation i[] = { I_OnReload, I_OnNickIdentify, I_OnDelCore };
ModuleManager::Attach(i, this, 3);
- OnReload(false);
+ OnReload();
}
- void OnReload(bool)
+ void OnReload()
{
ConfigReader config;
diff --git a/modules/extra/m_mysql.cpp b/modules/extra/m_mysql.cpp
index 9895d025d..a54426b37 100644
--- a/modules/extra/m_mysql.cpp
+++ b/modules/extra/m_mysql.cpp
@@ -158,7 +158,7 @@ class ModuleSQL : public Module, public Pipe
DThread = new DispatcherThread();
threadEngine.Start(DThread);
- OnReload(true);
+ OnReload();
}
~ModuleSQL()
@@ -173,7 +173,7 @@ class ModuleSQL : public Module, public Pipe
delete DThread;
}
- void OnReload(bool startup)
+ void OnReload()
{
ConfigReader config;
int i, num;
diff --git a/modules/extra/m_xmlrpc.cpp b/modules/extra/m_xmlrpc.cpp
index db1242970..34288195a 100644
--- a/modules/extra/m_xmlrpc.cpp
+++ b/modules/extra/m_xmlrpc.cpp
@@ -218,12 +218,12 @@ class ModuleXMLRPC : public Module
{
me = this;
- OnReload(false);
-
ModuleManager::RegisterService(&this->xmlrpcinterface);
Implementation i[] = { I_OnReload };
ModuleManager::Attach(i, this, 1);
+
+ OnReload();
}
~ModuleXMLRPC()
@@ -250,7 +250,7 @@ class ModuleXMLRPC : public Module
this->listen_sockets.clear();
}
- void OnReload(bool)
+ void OnReload()
{
ConfigReader config;
diff --git a/modules/extra/m_xmlrpc_main.cpp b/modules/extra/m_xmlrpc_main.cpp
index 593aba6ef..6f4b4b05c 100644
--- a/modules/extra/m_xmlrpc_main.cpp
+++ b/modules/extra/m_xmlrpc_main.cpp
@@ -87,14 +87,15 @@ class MyXMLRPCEvent : public XMLRPCEvent
else
request->reply("online", "yes");
- mod_run_cmd(bi, *u, NULL, command);
+ mod_run_cmd(bi, u, NULL, command);
if (created && u)
{
- XMLRPCUser *myu = debug_cast<XMLRPCUser *>(*u);
+ User *useru = u;
+ XMLRPCUser *myu = debug_cast<XMLRPCUser *>(useru);
if (!myu->GetOut().empty())
request->reply("return", iface->Sanitize(myu->GetOut()));
- delete *u;
+ delete u;
}
}
}
diff --git a/modules/extra/ns_maxemail.cpp b/modules/extra/ns_maxemail.cpp
index 94b4ef12c..2a0141508 100644
--- a/modules/extra/ns_maxemail.cpp
+++ b/modules/extra/ns_maxemail.cpp
@@ -59,13 +59,13 @@ class NSMaxEmail : public Module
this->SetAuthor("Anope");
this->SetType(SUPPORTED);
- ModuleManager::Attach(I_OnReload, this);
- ModuleManager::Attach(I_OnPreCommand, this);
+ Implementation i[] = { I_OnReload, I_OnPreCommand };
+ ModuleManager::Attach(i, this, 2);
- OnReload(false);
+ OnReload();
}
- void OnReload(bool)
+ void OnReload()
{
ConfigReader config;
this->NSEmailMax = config.ReadInteger("ns_maxemail", "maxemails", "0", 0, false);
@@ -75,7 +75,7 @@ class NSMaxEmail : public Module
EventReturn OnPreCommand(CommandSource &source, Command *command, const std::vector<Anope::string> &params)
{
BotInfo *service = source.owner;
- if (service == NickServ)
+ if (service->nick == Config->s_NickServ)
{
if (command->name.equals_ci("REGISTER"))
{
diff --git a/modules/extra/ns_set_misc.cpp b/modules/extra/ns_set_misc.cpp
index a1bf091c5..385fb9648 100644
--- a/modules/extra/ns_set_misc.cpp
+++ b/modules/extra/ns_set_misc.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSSetMisc : public Command
{
@@ -80,8 +81,8 @@ class NSSetMisc : public Module
if (Commands.empty())
return;
- Command *set = FindCommand(NickServ, "SET");
- Command *saset = FindCommand(NickServ, "SASET");
+ Command *set = FindCommand(nickserv->Bot(), "SET");
+ Command *saset = FindCommand(nickserv->Bot(), "SASET");
if (!set && !saset)
return;
@@ -120,7 +121,7 @@ class NSSetMisc : public Module
Implementation i[] = { I_OnReload, I_OnNickInfo, I_OnDatabaseWriteMetadata, I_OnDatabaseReadMetadata };
ModuleManager::Attach(i, this, 4);
- OnReload(true);
+ OnReload();
}
~NSSetMisc()
@@ -128,12 +129,12 @@ class NSSetMisc : public Module
RemoveAll();
}
- void OnReload(bool)
+ void OnReload()
{
RemoveAll();
- Command *set = FindCommand(NickServ, "SET");
- Command *saset = FindCommand(NickServ, "SASET");
+ Command *set = FindCommand(nickserv->Bot(), "SET");
+ Command *saset = FindCommand(nickserv->Bot(), "SASET");
if (!set && !saset)
return;
diff --git a/modules/extra/os_defcon.cpp b/modules/extra/os_defcon.cpp
new file mode 100644
index 000000000..a2a536adf
--- /dev/null
+++ b/modules/extra/os_defcon.cpp
@@ -0,0 +1,693 @@
+/* OperServ core functions
+ *
+ * (C) 2003-2011 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ */
+
+/*************************************************************************/
+
+#include "module.h"
+#include "operserv.h"
+#include "global.h"
+#include "os_session.h"
+
+enum DefconLevel
+{
+ DEFCON_NO_NEW_CHANNELS,
+ DEFCON_NO_NEW_NICKS,
+ DEFCON_NO_MLOCK_CHANGE,
+ DEFCON_FORCE_CHAN_MODES,
+ DEFCON_REDUCE_SESSION,
+ DEFCON_NO_NEW_CLIENTS,
+ DEFCON_OPER_ONLY,
+ DEFCON_SILENT_OPER_ONLY,
+ DEFCON_AKILL_NEW_CLIENTS,
+ DEFCON_NO_NEW_MEMOS
+};
+
+static Module *me = NULL;
+bool DefConModesSet = false;
+
+struct DefconConfig
+{
+ std::vector<std::bitset<32> > DefCon;
+ Flags<ChannelModeName, CMODE_END * 2> DefConModesOn;
+ Flags<ChannelModeName, CMODE_END * 2> DefConModesOff;
+ std::map<ChannelModeName, Anope::string> DefConModesOnParams;
+
+ int defaultlevel, sessionlimit;
+ Anope::string chanmodes, message, offmessage, akillreason;
+ std::vector<Anope::string> defcons;
+ time_t akillexpire, timeout;
+ bool globalondefcon;
+
+ DefconConfig()
+ {
+ this->DefCon.resize(5);
+ }
+
+ bool Check(DefconLevel level)
+ {
+ return this->Check(this->defaultlevel, level);
+ }
+
+ bool Check(int dlevel, DefconLevel level)
+ {
+ return this->DefCon[dlevel].test(level);
+ }
+
+ void Add(int dlevel, DefconLevel level)
+ {
+ this->DefCon[dlevel][level] = true;
+ }
+
+ void Del(int dlevel, DefconLevel level)
+ {
+ this->DefCon[dlevel][level] = false;
+ }
+
+ bool SetDefConParam(ChannelModeName Name, const Anope::string &buf)
+ {
+ return DefConModesOnParams.insert(std::make_pair(Name, buf)).second;
+ }
+
+ void UnsetDefConParam(ChannelModeName Name)
+ {
+ DefConModesOnParams.erase(Name);
+ }
+
+ bool GetDefConParam(ChannelModeName Name, Anope::string &buf)
+ {
+ std::map<ChannelModeName, Anope::string>::iterator it = DefConModesOnParams.find(Name);
+
+ buf.clear();
+
+ if (it != DefConModesOnParams.end())
+ {
+ buf = it->second;
+ return true;
+ }
+
+ return false;
+ }
+};
+
+static DefconConfig DConfig;
+
+/**************************************************************************/
+
+void defcon_sendlvls(CommandSource &source);
+void runDefCon();
+static Anope::string defconReverseModes(const Anope::string &modes);
+
+class DefConTimeout : public CallBack
+{
+ int level;
+
+ public:
+ DefConTimeout(Module *mod, int newlevel) : CallBack(mod, DConfig.timeout), level(newlevel) { }
+
+ void Tick(time_t)
+ {
+ if (DConfig.defaultlevel != level)
+ {
+ DConfig.defaultlevel = level;
+ FOREACH_MOD(I_OnDefconLevel, OnDefconLevel(level));
+ Log(operserv->Bot(), "operserv/defcon") << "Defcon level timeout, returning to level " << level;
+ ircdproto->SendGlobops(operserv->Bot(), GetString(NULL, _("\002%s\002 Changed the DEFCON level to \002%d\002")).c_str(), Config->s_OperServ.c_str(), level);
+
+ if (DConfig.globalondefcon)
+ {
+ if (!DConfig.offmessage.empty())
+ global->SendGlobal(global->Bot(), "", DConfig.offmessage);
+ else
+ global->SendGlobal(global->Bot(), "", Anope::printf(GetString(NULL, _("The Defcon Level is now at Level: \002%d\002")).c_str(), DConfig.defaultlevel));
+
+ if (!DConfig.message.empty())
+ global->SendGlobal(global->Bot(), "", DConfig.message);
+ }
+
+ runDefCon();
+ }
+ }
+};
+static DefConTimeout *timeout;
+
+class CommandOSDefcon : public Command
+{
+ void SendLevels(CommandSource &source)
+ {
+ if (DConfig.Check(DEFCON_NO_NEW_CHANNELS))
+ source.Reply(_("* No new channel registrations"));
+ if (DConfig.Check(DEFCON_NO_NEW_NICKS))
+ source.Reply(_("* No new nick registrations"));
+ if (DConfig.Check(DEFCON_NO_MLOCK_CHANGE))
+ source.Reply(_("* No MLOCK changes"));
+ if (DConfig.Check(DEFCON_FORCE_CHAN_MODES) && !DConfig.chanmodes.empty())
+ source.Reply(_("* Force Chan Modes (%s) to be set on all channels"), DConfig.chanmodes.c_str());
+ if (DConfig.Check(DEFCON_REDUCE_SESSION))
+ source.Reply(_("* Use the reduced session limit of %d"), DConfig.sessionlimit);
+ if (DConfig.Check(DEFCON_NO_NEW_CLIENTS))
+ source.Reply(_("* Kill any NEW clients connecting"));
+ if (DConfig.Check(DEFCON_OPER_ONLY))
+ source.Reply(_("* Ignore any non-opers with message"));
+ if (DConfig.Check(DEFCON_SILENT_OPER_ONLY))
+ source.Reply(_("* Silently ignore non-opers"));
+ if (DConfig.Check(DEFCON_AKILL_NEW_CLIENTS))
+ source.Reply(_("* AKILL any new clients connecting"));
+ if (DConfig.Check(DEFCON_NO_NEW_MEMOS))
+ source.Reply(_("* No new memos sent"));
+ }
+
+ public:
+ CommandOSDefcon() : Command("DEFCON", 1, 1, "operserv/defcon")
+ {
+ this->SetDesc(_("Manipulate the DefCon system"));
+ }
+
+ CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ User *u = source.u;
+ const Anope::string &lvl = params[0];
+
+ if (lvl.empty())
+ {
+ source.Reply(_("Services are now at DEFCON \002%d\002"), DConfig.defaultlevel);
+ this->SendLevels(source);
+ return MOD_CONT;
+ }
+
+ int newLevel = 0;
+ try
+ {
+ newLevel = convertTo<int>(lvl);
+ }
+ catch (const ConvertException &) { }
+
+ if (newLevel < 1 || newLevel > 5)
+ {
+ this->OnSyntaxError(source, "");
+ return MOD_CONT;
+ }
+
+ DConfig.defaultlevel = newLevel;
+
+ FOREACH_MOD(I_OnDefconLevel, OnDefconLevel(newLevel));
+
+ if (timeout)
+ {
+ delete timeout;
+ timeout = NULL;
+ }
+
+ if (DConfig.timeout)
+ timeout = new DefConTimeout(me, 5);
+
+ source.Reply(_("Services are now at DEFCON \002%d\002"), DConfig.defaultlevel);
+ this->SendLevels(source);
+ Log(LOG_ADMIN, u, this) << "to change defcon level to " << newLevel;
+ ircdproto->SendGlobops(operserv->Bot(), _("\002%s\002 Changed the DEFCON level to \002%d\002"), u->nick.c_str(), newLevel);
+ /* Global notice the user what is happening. Also any Message that
+ the Admin would like to add. Set in config file. */
+ if (DConfig.globalondefcon)
+ {
+ if (DConfig.defaultlevel == 5 && !DConfig.offmessage.empty())
+ global->SendGlobal(global->Bot(), "", DConfig.offmessage);
+ else if (DConfig.defaultlevel != 5)
+ {
+ global->SendGlobal(global->Bot(), "", Anope::printf(_("The Defcon level is now at: \002%d\002"), DConfig.defaultlevel));
+ if (!DConfig.message.empty())
+ global->SendGlobal(global->Bot(), "", DConfig.message);
+ }
+ }
+
+ /* Run any defcon functions, e.g. FORCE CHAN MODE */
+ runDefCon();
+ return MOD_CONT;
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand)
+ {
+ source.Reply(_("Syntax: \002DEFCON\002 [\0021\002|\0022\002|\0023\002|\0024\002|\0025\002]\n"
+ "The defcon system can be used to implement a pre-defined\n"
+ "set of restrictions to services useful during an attempted\n"
+ "attack on the network."));
+ return true;
+ }
+
+ void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
+ {
+ SyntaxError(source, "DEFCON", _("DEFCON [\0021\002|\0022\002|\0023\002|\0024\002|\0025\002]"));
+ }
+};
+
+class OSDefcon : public Module
+{
+ service_reference<SessionService> session_service;
+ CommandOSDefcon commandosdefcon;
+
+ void ParseModeString()
+ {
+ int add = -1; /* 1 if adding, 0 if deleting, -1 if neither */
+ unsigned char mode;
+ ChannelMode *cm;
+ ChannelModeParam *cmp;
+ Anope::string modes, param;
+
+ spacesepstream ss(DConfig.chanmodes);
+
+ DConfig.DefConModesOn.ClearFlags();
+ DConfig.DefConModesOff.ClearFlags();
+ ss.GetToken(modes);
+
+ /* Loop while there are modes to set */
+ for (unsigned i = 0, end = modes.length(); i < end; ++i)
+ {
+ mode = modes[i];
+
+ switch (mode)
+ {
+ case '+':
+ add = 1;
+ continue;
+ case '-':
+ add = 0;
+ continue;
+ default:
+ if (add < 0)
+ continue;
+ }
+
+ if ((cm = ModeManager::FindChannelModeByChar(mode)))
+ {
+ if (cm->Type == MODE_STATUS || cm->Type == MODE_LIST || !cm->CanSet(NULL))
+ {
+ Log() << "DefConChanModes mode character '" << mode << "' cannot be locked";
+ continue;
+ }
+ else if (add)
+ {
+ DConfig.DefConModesOn.SetFlag(cm->Name);
+ DConfig.DefConModesOff.UnsetFlag(cm->Name);
+
+ if (cm->Type == MODE_PARAM)
+ {
+ cmp = debug_cast<ChannelModeParam *>(cm);
+
+ if (!ss.GetToken(param))
+ {
+ Log() << "DefConChanModes mode character '" << mode << "' has no parameter while one is expected";
+ continue;
+ }
+
+ if (!cmp->IsValid(param))
+ continue;
+
+ DConfig.SetDefConParam(cmp->Name, param);
+ }
+ }
+ else if (DConfig.DefConModesOn.HasFlag(cm->Name))
+ {
+ DConfig.DefConModesOn.UnsetFlag(cm->Name);
+
+ if (cm->Type == MODE_PARAM)
+ DConfig.UnsetDefConParam(cm->Name);
+ }
+ }
+ }
+
+ /* We can't mlock +L if +l is not mlocked as well. */
+ if ((cm = ModeManager::FindChannelModeByName(CMODE_REDIRECT)) && DConfig.DefConModesOn.HasFlag(cm->Name) && !DConfig.DefConModesOn.HasFlag(CMODE_LIMIT))
+ {
+ DConfig.DefConModesOn.UnsetFlag(CMODE_REDIRECT);
+
+ Log() << "DefConChanModes must lock mode +l as well to lock mode +L";
+ }
+
+ /* Some ircd we can't set NOKNOCK without INVITE */
+ /* So check if we need there is a NOKNOCK MODE and that we need INVITEONLY */
+ if (ircd->knock_needs_i && (cm = ModeManager::FindChannelModeByName(CMODE_NOKNOCK)) && DConfig.DefConModesOn.HasFlag(cm->Name) && !DConfig.DefConModesOn.HasFlag(CMODE_INVITE))
+ {
+ DConfig.DefConModesOn.UnsetFlag(CMODE_NOKNOCK);
+ Log() << "DefConChanModes must lock mode +i as well to lock mode +K";
+ }
+ }
+
+ public:
+ OSDefcon(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), session_service("session")
+ {
+ if (!DConfig.defaultlevel)
+ throw ModuleException("Invalid configuration settings");
+
+ me = this;
+
+ this->SetAuthor("Anope");
+ this->SetType(CORE);
+
+ Implementation i[] = { I_OnReload, I_OnChannelModeSet, I_OnChannelModeUnset, I_OnPreCommandRun, I_OnPreCommand, I_OnUserConnect, I_OnChannelModeAdd, I_OnChannelCreate };
+ ModuleManager::Attach(i, this, 9);
+
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ this->AddCommand(operserv->Bot(), &commandosdefcon);
+
+ this->OnReload();
+ }
+
+ void OnReload()
+ {
+ ConfigReader config;
+ DefconConfig dconfig;
+
+ dconfig.defaultlevel = config.ReadInteger("defcon", "defaultlevel", 0, 0);
+ dconfig.defcons[4] = config.ReadValue("defcon", "level4", 0);
+ dconfig.defcons[3] = config.ReadValue("defcon", "level3", 0);
+ dconfig.defcons[2] = config.ReadValue("defcon", "level2", 0);
+ dconfig.defcons[1] = config.ReadValue("defcon", "level1", 0);
+ dconfig.sessionlimit = config.ReadInteger("defcon", "sessionlimit", 0, 0);
+ dconfig.akillexpire = dotime(config.ReadValue("defcon", "akillexpire", 0));
+ dconfig.chanmodes = config.ReadValue("defcon", "chanmodes", 0);
+ dconfig.timeout = dotime(config.ReadValue("defcon", "timeout", 0));
+ dconfig.globalondefcon = config.ReadFlag("defcon", "globalondefcon", 0);
+ dconfig.message = config.ReadValue("defcon", "message", 0);
+ dconfig.offmessage = config.ReadValue("defcon", "offmessage", 0);
+
+ if (dconfig.defaultlevel < 1 || dconfig.defaultlevel > 5)
+ throw ConfigException("The value for <os_defcon:defaultlevel> must be between 1 and 5");
+ else if (dconfig.akillexpire <= 0)
+ throw ConfigException("The value for <os_defcon:akillexpire> must be greater than zero!");
+
+ for (unsigned level = 1; level < 5; ++level)
+ {
+ spacesepstream operations(dconfig.defcons[level]);
+ Anope::string operation;
+ while (operations.GetToken(operation))
+ {
+ if (operation.equals_ci("nonewchannels"))
+ dconfig.Add(level, DEFCON_NO_NEW_CHANNELS);
+ else if (operation.equals_ci("nonewnicks"))
+ dconfig.Add(level, DEFCON_NO_NEW_NICKS);
+ else if (operation.equals_ci("nomlockchanges"))
+ dconfig.Add(level, DEFCON_NO_MLOCK_CHANGE);
+ else if (operation.equals_ci("forcechanmodes"))
+ dconfig.Add(level, DEFCON_FORCE_CHAN_MODES);
+ else if (operation.equals_ci("reducedsessions"))
+ dconfig.Add(level, DEFCON_REDUCE_SESSION);
+ else if (operation.equals_ci("nonewclients"))
+ dconfig.Add(level, DEFCON_NO_NEW_CLIENTS);
+ else if (operation.equals_ci("operonly"))
+ dconfig.Add(level, DEFCON_OPER_ONLY);
+ else if (operation.equals_ci("silentoperonly"))
+ dconfig.Add(level, DEFCON_SILENT_OPER_ONLY);
+ else if (operation.equals_ci("akillnewclients"))
+ dconfig.Add(level, DEFCON_AKILL_NEW_CLIENTS);
+ else if (operation.equals_ci("nonewmemos"))
+ dconfig.Add(level, DEFCON_NO_NEW_MEMOS);
+ }
+
+ if (dconfig.Check(level, DEFCON_REDUCE_SESSION) && dconfig.sessionlimit <= 0)
+ throw ConfigException("The value for <os_defcon:sessionlimit> must be greater than zero!");
+ else if (dconfig.Check(level, DEFCON_AKILL_NEW_CLIENTS) && dconfig.akillreason.empty())
+ throw ConfigException("The value for <os_defcon:akillreason> must not be empty!");
+ else if (dconfig.Check(level, DEFCON_FORCE_CHAN_MODES) && dconfig.chanmodes.empty())
+ throw ConfigException("The value for <os_defcon:chanmodes> must not be empty!");
+ }
+
+ DConfig = dconfig;
+ this->ParseModeString();
+ }
+
+ EventReturn OnUserConnect(User *u, bool &exempt)
+ {
+ if (!exempt && u->server->IsSynced() && DConfig.Check(DEFCON_AKILL_NEW_CLIENTS) && !u->server->IsULined())
+ {
+ if (DConfig.Check(DEFCON_AKILL_NEW_CLIENTS))
+ {
+ Log(operserv->Bot(), "operserv/defcon") << "DEFCON: adding akill for *@" << u->host;
+ XLine *x = SGLine->Add("*@" + u->host, Config->s_OperServ, Anope::CurTime + DConfig.akillexpire, DConfig.akillreason);
+ if (x)
+ x->By = Config->s_OperServ;
+ }
+
+ if (DConfig.Check(DEFCON_NO_NEW_CLIENTS) || DConfig.Check(DEFCON_AKILL_NEW_CLIENTS))
+ kill_user(Config->s_OperServ, u, DConfig.akillreason);
+
+ return EVENT_STOP;
+ }
+
+ return EVENT_CONTINUE;
+ }
+
+ EventReturn OnChannelModeSet(Channel *c, ChannelModeName Name, const Anope::string &param)
+ {
+ ChannelMode *cm = ModeManager::FindChannelModeByName(Name);
+
+ if (DConfig.Check(DEFCON_FORCE_CHAN_MODES) && cm && DConfig.DefConModesOff.HasFlag(Name))
+ {
+ c->RemoveMode(operserv->Bot(), Name, param);
+
+ return EVENT_STOP;
+ }
+
+ return EVENT_CONTINUE;
+ }
+
+ EventReturn OnChannelModeUnset(Channel *c, ChannelModeName Name, const Anope::string &)
+ {
+ ChannelMode *cm = ModeManager::FindChannelModeByName(Name);
+
+ if (DConfig.Check(DEFCON_FORCE_CHAN_MODES) && cm && DConfig.DefConModesOn.HasFlag(Name))
+ {
+ Anope::string param;
+
+ if (DConfig.GetDefConParam(Name, param))
+ c->SetMode(operserv->Bot(), Name, param);
+ else
+ c->SetMode(operserv->Bot(), Name);
+
+ return EVENT_STOP;
+
+ }
+
+ return EVENT_CONTINUE;
+ }
+
+ EventReturn OnPreCommandRun(User *&u, BotInfo *&bi, Anope::string &command, Anope::string &message, ChannelInfo *&ci)
+ {
+ if (!u->HasMode(UMODE_OPER) && (DConfig.Check(DEFCON_OPER_ONLY) || DConfig.Check(DEFCON_SILENT_OPER_ONLY)))
+ {
+ if (!DConfig.Check(DEFCON_SILENT_OPER_ONLY))
+ u->SendMessage(bi, _("Services are in Defcon mode, Please try again later."));
+
+ return EVENT_STOP;
+ }
+
+ return EVENT_CONTINUE;
+ }
+
+ EventReturn OnPreCommand(CommandSource &source, Command *command, const std::vector<Anope::string> &params)
+ {
+ BotInfo *service = command->service;
+ if (service->nick == Config->s_NickServ)
+ {
+ if (command->name.equals_ci("REGISTER") || command->name.equals_ci("GROUP"))
+ {
+ if (DConfig.Check(DEFCON_NO_NEW_NICKS))
+ {
+ source.Reply(_("Services are in Defcon mode, Please try again later."));
+ return EVENT_STOP;
+ }
+ }
+ }
+ else if (service->nick == Config->s_ChanServ)
+ {
+ if (command->name.equals_ci("SET"))
+ {
+ if (!params.empty() && params[0].equals_ci("MLOCK") && DConfig.Check(DEFCON_NO_MLOCK_CHANGE))
+ {
+ source.Reply(_("Services are in Defcon mode, Please try again later."));
+ return EVENT_STOP;
+ }
+ }
+ else if (command->name.equals_ci("REGISTER"))
+ {
+ if (DConfig.Check(DEFCON_NO_NEW_CHANNELS))
+ {
+ source.Reply(_("Services are in Defcon mode, Please try again later."));
+ return EVENT_STOP;
+ }
+ }
+ }
+ else if (service->nick == Config->s_MemoServ)
+ {
+ if (command->name.equals_ci("SEND") || command->name.equals_ci("SENDALL"))
+ {
+ if (DConfig.Check(DEFCON_NO_NEW_MEMOS))
+ {
+ source.Reply(_("Services are in Defcon mode, Please try again later."));
+ return EVENT_STOP;
+ }
+ }
+ }
+
+ return EVENT_CONTINUE;
+ }
+
+ void OnUserConnect(dynamic_reference<User> &u, bool &exempt)
+ {
+ if (exempt || !u || !u->server->IsSynced() || u->server->IsULined())
+ return;
+
+ if (DConfig.Check(DEFCON_AKILL_NEW_CLIENTS))
+ {
+ if (DConfig.Check(DEFCON_AKILL_NEW_CLIENTS))
+ {
+ Log(operserv->Bot(), "operserv/defcon") << "DEFCON: adding akill for *@" << u->host;
+ XLine *x = SGLine->Add("*@" + u->host, Config->s_OperServ, Anope::CurTime + DConfig.akillexpire, DConfig.akillreason);
+ if (x)
+ x->By = Config->s_OperServ;
+ }
+
+ if (DConfig.Check(DEFCON_NO_NEW_CLIENTS) || DConfig.Check(DEFCON_AKILL_NEW_CLIENTS))
+ {
+ kill_user(Config->s_OperServ, u, DConfig.akillreason);
+ return;
+ }
+ }
+
+ if (!DConfig.sessionlimit)
+ return;
+
+ if (DConfig.Check(DEFCON_AKILL_NEW_CLIENTS))
+ {
+ Log(operserv->Bot(), "operserv/defcon") << "DEFCON: adding akill for *@" << u->host;
+ XLine *x = SGLine->Add("*@" + u->host, Config->s_OperServ, Anope::CurTime + DConfig.akillexpire, !DConfig.akillreason.empty() ? DConfig.akillreason : "DEFCON AKILL");
+ if (x)
+ x->By = Config->s_OperServ;
+ }
+
+ if (DConfig.Check(DEFCON_NO_NEW_CLIENTS) || DConfig.Check(DEFCON_AKILL_NEW_CLIENTS))
+ {
+ kill_user(Config->s_OperServ, u, DConfig.akillreason);
+ return;
+ }
+
+ Session *session = session_service->FindSession(u->host);
+ Exception *exception = session_service->FindException(u);
+
+ if (DConfig.Check(DEFCON_REDUCE_SESSION) && !exception)
+ {
+ if (session && session->count > DConfig.sessionlimit)
+ {
+ if (!Config->SessionLimitExceeded.empty())
+ ircdproto->SendMessage(operserv->Bot(), u->nick, Config->SessionLimitExceeded.c_str(), u->host.c_str());
+ if (!Config->SessionLimitDetailsLoc.empty())
+ ircdproto->SendMessage(operserv->Bot(), u->nick, "%s", Config->SessionLimitDetailsLoc.c_str());
+
+ kill_user(Config->s_OperServ, u, "Defcon session limit exceeded");
+ ++session->hits;
+ if (Config->MaxSessionKill && session->hits >= Config->MaxSessionKill)
+ {
+ SGLine->Add("*@" + u->host, Config->s_OperServ, Anope::CurTime + Config->SessionAutoKillExpiry, "Defcon session limit exceeded");
+ ircdproto->SendGlobops(operserv->Bot(), "[DEFCON] Added a temporary AKILL for \2*@%s\2 due to excessive connections", u->host.c_str());
+ }
+ }
+ }
+ }
+
+ void OnChannelModeAdd(ChannelMode *cm)
+ {
+ if (DConfig.chanmodes.find(cm->ModeChar) != Anope::string::npos)
+ this->ParseModeString();
+ }
+
+ void OnChannelCreate(Channel *c)
+ {
+ if (DConfig.Check(DEFCON_FORCE_CHAN_MODES))
+ c->SetModes(operserv->Bot(), false, "%s", DConfig.chanmodes.c_str());
+ }
+};
+
+/**
+ * Send a message to the oper about which precautions are "active" for this level
+ **/
+void defcon_sendlvls(CommandSource &source)
+{
+ if (DConfig.Check(DEFCON_NO_NEW_CHANNELS))
+ source.Reply(_("* No new channel registrations"));
+ if (DConfig.Check(DEFCON_NO_NEW_NICKS))
+ source.Reply(_("* No new nick registrations"));
+ if (DConfig.Check(DEFCON_NO_MLOCK_CHANGE))
+ source.Reply(_("* No MLOCK changes"));
+ if (DConfig.Check(DEFCON_FORCE_CHAN_MODES) && !DConfig.chanmodes.empty())
+ source.Reply(_("* Force Chan Modes (%s) to be set on all channels"), DConfig.chanmodes.c_str());
+ if (DConfig.Check(DEFCON_REDUCE_SESSION))
+ source.Reply(_("* Use the reduced session limit of %d"), DConfig.sessionlimit);
+ if (DConfig.Check(DEFCON_NO_NEW_CLIENTS))
+ source.Reply(_("* Kill any NEW clients connecting"));
+ if (DConfig.Check(DEFCON_OPER_ONLY))
+ source.Reply(_("* Ignore any non-opers with message"));
+ if (DConfig.Check(DEFCON_SILENT_OPER_ONLY))
+ source.Reply(_("* Silently ignore non-opers"));
+ if (DConfig.Check(DEFCON_AKILL_NEW_CLIENTS))
+ source.Reply(_("* AKILL any new clients connecting"));
+ if (DConfig.Check(DEFCON_NO_NEW_MEMOS))
+ source.Reply(_("* No new memos sent"));
+}
+
+void runDefCon()
+{
+ if (DConfig.Check(DEFCON_FORCE_CHAN_MODES))
+ {
+ if (!DConfig.chanmodes.empty() && !DefConModesSet)
+ {
+ if (DConfig.chanmodes[0] == '+' || DConfig.chanmodes[0] == '-')
+ {
+ Log(operserv->Bot(), "operserv/defcon") << "DEFCON: setting " << DConfig.chanmodes << " on all channels";
+ DefConModesSet = true;
+ MassChannelModes(operserv->Bot(), DConfig.chanmodes);
+ }
+ }
+ }
+ else
+ {
+ if (!DConfig.chanmodes.empty() && DefConModesSet)
+ {
+ if (DConfig.chanmodes[0] == '+' || DConfig.chanmodes[0] == '-')
+ {
+ DefConModesSet = false;
+ Anope::string newmodes = defconReverseModes(DConfig.chanmodes);
+ if (!newmodes.empty())
+ {
+ Log(operserv->Bot(), "operserv/defcon") << "DEFCON: setting " << newmodes << " on all channels";
+ MassChannelModes(operserv->Bot(), newmodes);
+ }
+ }
+ }
+ }
+}
+
+static Anope::string defconReverseModes(const Anope::string &modes)
+{
+ if (modes.empty())
+ return "";
+ Anope::string newmodes;
+ for (unsigned i = 0, end = modes.length(); i < end; ++i)
+ {
+ if (modes[i] == '+')
+ newmodes += '-';
+ else if (modes[i] == '-')
+ newmodes += '+';
+ else
+ newmodes += modes[i];
+ }
+ return newmodes;
+}
+
+MODULE_INIT(OSDefcon)