1
0
mirror of https://github.com/anope/anope.git synced 2026-07-01 10:06:37 +02:00

Rewrote all of the defcon code, and moved most of it to os_defcon. This fixes defcon to have the ability to use modes introduced to Anope at a later time than on startup (eg, from the IRCd), amongst other things

git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@2597 5417fbe8-f217-4b02-8779-1006273d7864
This commit is contained in:
Adam-
2009-10-30 01:04:13 +00:00
parent 5fc268b750
commit 6a9fa9f4d2
22 changed files with 546 additions and 396 deletions
+6 -6
View File
@@ -389,9 +389,6 @@ E int NumUlines;
E int read_config(int reload);
E int DefConLevel;
E int DefCon[6];
E int checkDefCon(int level);
E void resetDefCon(int level);
E int DefConSessionLimit;
E time_t DefConTimeOut;
E time_t DefConAKILL;
@@ -692,10 +689,13 @@ E int check_szline(const char *nick, char *ip);
E Server *server_global(Server * s, char *msg);
E bool CheckDefCon(DefconLevel Level);
E bool CheckDefCon(int level, DefconLevel Level);
E void AddDefCon(int level, DefconLevel Level);
E void DelDefCon(int level, DefconLevel Level);
E std::vector<std::bitset<32> > DefCon;
E bool OSOpersOnly;
E time_t DefContimer;
E void runDefCon();
E int defconParseModeString(const char *str);
/**** process.c ****/
+23 -8
View File
@@ -558,6 +558,15 @@ class CoreExport Module
*/
virtual void OnUserNickChange(User *u, const char *oldnick) { }
/** Called immediatly when a user tries to run a command
* @param service The service
* @param u The user
* @param cmd The command
* @param c The command class (if it exists)
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it
*/
virtual EventReturn OnPreCommandRun(const char *service, User *u, const char *cmd, Command *c) { return EVENT_CONTINUE; }
/** Called before a command is due to be executed.
* @param u The user executing the command
* @param service The service the command is associated with
@@ -726,7 +735,7 @@ class CoreExport Module
/** Called when defcon level changes
* @param level The level
*/
virtual void OnDefconLevel(const char *level) { }
virtual void OnDefconLevel(int level) { }
/** Called when a server quits
* @param server The server
@@ -818,6 +827,16 @@ class CoreExport Module
*/
virtual void OnDelChan(ChannelInfo *ci) { }
/** Called when a new channel is created
* @param c The channel
*/
virtual void OnChannelCreate(Channel *c) { }
/** Called when a channel is deleted
* @param c The channel
*/
virtual void OnChannelDelete(Channel *c) { }
/** Called when a nick is dropped
* @param nick The nick
*/
@@ -859,11 +878,6 @@ class CoreExport Module
*/
virtual void OnNickUnsuspended(NickAlias *na) { }
/** Called when the defcon level is changed
* @param level The level
*/
virtual void OnDefconLevel(int level) { }
/** Called on finduser()
* @param u pointer to the user
*/
@@ -985,7 +999,8 @@ enum Implementation
/* ChanServ */
I_OnChanForbidden, I_OnChanSuspend, I_OnChanDrop, I_OnChanExpire, I_OnAccessAdd, I_OnAccessChange,
I_OnAccessDel, I_OnAccessClear, I_OnChanRegistered, I_OnChanUnsuspend, I_OnDelChan,
I_OnAccessDel, I_OnAccessClear, I_OnChanRegistered, I_OnChanUnsuspend, I_OnDelChan, I_OnChannelCreate,
I_OnChannelDelete,
/* BotServ */
I_OnBotJoin, I_OnBotKick, I_OnBotCreate, I_OnBotChange, I_OnBotDelete, I_OnBotAssign, I_OnBotUnAssign,
@@ -1002,7 +1017,7 @@ enum Implementation
I_OnDefconLevel,
/* Other */
I_OnReload, I_OnPreServerConnect, I_OnNewServer, I_OnServerConnect, I_OnPreCommand, I_OnPostCommand, I_OnPostLoadDatabases, I_OnSaveDatabase, I_OnBackupDatabase,
I_OnReload, I_OnPreServerConnect, I_OnNewServer, I_OnServerConnect, I_OnPreCommandRun, I_OnPreCommand, I_OnPostCommand, I_OnPostLoadDatabases, I_OnSaveDatabase, I_OnBackupDatabase,
I_OnPreDatabaseExpire, I_OnDatabaseExpire, I_OnPreRestart, I_OnRestart, I_OnPreShutdown, I_OnShutdown, I_OnSignal,
I_OnServerQuit, I_OnTopicUpdated,
I_OnEncrypt, I_OnEncryptInPlace, I_OnEncryptCheckLen, I_OnDecrypt, I_OnCheckPassword,
+16 -13
View File
@@ -1426,19 +1426,22 @@ struct session_ {
};
/*************************************************************************/
/**
* DEFCON Defines
**/
#define DEFCON_NO_NEW_CHANNELS 1 /* No New Channel Registrations */
#define DEFCON_NO_NEW_NICKS 2 /* No New Nick Registrations */
#define DEFCON_NO_MLOCK_CHANGE 4 /* No MLOCK changes */
#define DEFCON_FORCE_CHAN_MODES 8 /* Force Chan Mode */
#define DEFCON_REDUCE_SESSION 16 /* Reduce Session Limit */
#define DEFCON_NO_NEW_CLIENTS 32 /* Kill any NEW clients */
#define DEFCON_OPER_ONLY 64 /* Restrict services to oper's only */
#define DEFCON_SILENT_OPER_ONLY 128 /* Silently ignore non-opers */
#define DEFCON_AKILL_NEW_CLIENTS 256 /* AKILL any new clients */
#define DEFCON_NO_NEW_MEMOS 512 /* No New Memos Sent */
/* Defcon */
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
};
/*************************************************************************/
+4
View File
@@ -1884,6 +1884,8 @@ Channel *chan_create(const char *chan, time_t ts)
restore_topic(chan);
}
FOREACH_MOD(I_OnChannelCreate, OnChannelCreate(c));
return c;
}
@@ -1895,6 +1897,8 @@ void chan_delete(Channel * c)
{
BanData *bd, *next;
FOREACH_MOD(I_OnChannelDelete, OnChannelDelete(c));
if (debug)
alog("debug: Deleting channel %s", c->name);
+8 -23
View File
@@ -813,8 +813,7 @@ void check_modes(Channel * c)
c->RemoveMode(CMODE_REGISTERED);
ircdproto->SendMode(whosends(ci), c->name, "-r");
}
/* Channels that are not regged also need the defcon modes.. ~ Viper */
/* return; */
return;
}
*end++ = '+';
@@ -823,8 +822,8 @@ void check_modes(Channel * c)
{
cm = it->second;
/* If this channel does not have the mode and the mode is mlocked/defcon'd */
if (!c->HasMode(cm->Name) && (ci && ci->HasMLock(cm->Name, true)) || (DefConModesSet && DefConModesCI.HasMLock(cm->Name, true)))
/* If this channel does not have the mode and the mode is mlocked */
if (!c->HasMode(cm->Name) && ci->HasMLock(cm->Name, true))
{
*end++ = it->first;
c->SetMode(cm->Name);
@@ -833,14 +832,7 @@ void check_modes(Channel * c)
if (cm->Type == MODE_PARAM)
{
cmp = static_cast<ChannelModeParam *>(cm);
param.clear();
if (DefConModesSet && DefConModesCI.HasMLock(cm->Name, true))
DefConModesCI.GetParam(cmp->Name, &param);
else if (ci)
ci->GetParam(cmp->Name, &param);
else
alog("Warning: Got no param for mode %c on channel %s but was expecting one", cmp->ModeChar, c->name);
ci->GetParam(cmp->Name, &param);
if (!param.empty())
{
@@ -852,19 +844,12 @@ void check_modes(Channel * c)
}
}
}
/* If this is a param mode and its mlocked or defcon has it set negative */
else if (cm->Type == MODE_PARAM && c->HasMode(cm->Name) && (ci && ci->HasMLock(cm->Name, true) || (DefConModesSet && DefConModesCI.HasMLock(cm->Name, true))))
/* If this is a param mode and its mlocked and is set negative */
else if (cm->Type == MODE_PARAM && c->HasMode(cm->Name) && ci->HasMLock(cm->Name, true))
{
cmp = static_cast<ChannelModeParam *>(cm);
c->GetParam(cmp->Name, &param);
if (DefConModesSet && DefConModesCI.HasMLock(cm->Name, true))
DefConModesCI.GetParam(cmp->Name, &ciparam);
else if (ci)
ci->GetParam(cmp->Name, &ciparam);
else
alog("Warning: Got no param for mode %c on channel %s but was expecting one", cmp->ModeChar, c->name);
ci->GetParam(cmp->Name, &ciparam);
if (!param.empty() && !ciparam.empty() && param != ciparam)
{
@@ -889,7 +874,7 @@ void check_modes(Channel * c)
cm = it->second;
/* If the channel has the mode */
if (c->HasMode(cm->Name) && (ci && ci->HasMLock(cm->Name, false)) || (DefConModesSet && DefConModesCI.HasMLock(cm->Name, false)))
if (c->HasMode(cm->Name) && ci->HasMLock(cm->Name, false))
{
*end++ = it->first;
c->RemoveMode(cm->Name);
+6 -14
View File
@@ -54,25 +54,18 @@ void mod_run_cmd(char *service, User * u, CommandHash * cmdTable[], const char *
Command *c = findCommand(cmdTable, cmd);
int retVal = MOD_CONT;
ChannelInfo *ci;
EventReturn MOD_RESULT;
FOREACH_RESULT(I_OnPreCommandRun, OnPreCommandRun(service, u, cmd, c));
if (MOD_RESULT == EVENT_STOP)
return;
if (!c)
{
if ((!checkDefCon(DEFCON_SILENT_OPER_ONLY)) || is_oper(u))
{
notice_lang(service, u, UNKNOWN_COMMAND_HELP, cmd, service);
}
notice_lang(service, u, UNKNOWN_COMMAND_HELP, cmd, service);
return;
}
if ((checkDefCon(DEFCON_OPER_ONLY) || checkDefCon(DEFCON_SILENT_OPER_ONLY)) && !is_oper(u))
{
if (!checkDefCon(DEFCON_SILENT_OPER_ONLY))
{
notice_lang(service, u, OPER_DEFCON_DENIED);
return;
}
}
if (!c->HasFlag(CFLAG_ALLOW_UNREGISTERED))
{
// Command requires registered users only
@@ -120,7 +113,6 @@ void mod_run_cmd(char *service, User * u, CommandHash * cmdTable[], const char *
return;
}
EventReturn MOD_RESULT = EVENT_CONTINUE;
FOREACH_RESULT(I_OnPreCommand, OnPreCommand(u, c->service, c->name.c_str(), params));
if (MOD_RESULT == EVENT_STOP)
return;
+23 -18
View File
@@ -235,7 +235,6 @@ static std::string DefCon1;
static std::string DefCon2;
static std::string DefCon3;
static std::string DefCon4;
int DefCon[6];
time_t DefConTimeOut;
int DefConSessionLimit;
time_t DefConAKILL;
@@ -1952,8 +1951,9 @@ int read_config(int reload)
**/
if (DefConLevel) {
/* Build DefCon's */
DefCon[0] = 0;
for (int level = 1; level < 5; ++level) {
DefCon.reserve(6);
DefCon[5].reset();
for (unsigned int level = 1; level < 5; ++level) {
DefCon[level] = 0;
std::string *levelDefinition = NULL;
switch (level) {
@@ -1972,28 +1972,33 @@ int read_config(int reload)
spacesepstream operations(*levelDefinition);
std::string operation;
while (operations.GetToken(operation)) {
if (operation == "nonewchannels") DefCon[level] |= DEFCON_NO_NEW_CHANNELS;
else if (operation == "nonewnicks") DefCon[level] |= DEFCON_NO_NEW_NICKS;
else if (operation == "nomlockchanges") DefCon[level] |= DEFCON_NO_MLOCK_CHANGE;
else if (operation == "forcechanmodes") DefCon[level] |= DEFCON_FORCE_CHAN_MODES;
else if (operation == "reducedsessions") DefCon[level] |= DEFCON_REDUCE_SESSION;
else if (operation == "nonewclients") DefCon[level] |= DEFCON_NO_NEW_CLIENTS;
else if (operation == "operonly") DefCon[level] |= DEFCON_OPER_ONLY;
else if (operation == "silentoperonly") DefCon[level] |= DEFCON_SILENT_OPER_ONLY;
else if (operation == "akillnewclients") DefCon[level] |= DEFCON_AKILL_NEW_CLIENTS;
else if (operation == "nonewmemos") DefCon[level] |= DEFCON_NO_NEW_MEMOS;
if (operation == "nonewchannels") AddDefCon(level, DEFCON_NO_NEW_CHANNELS);
else if (operation == "nonewnicks") AddDefCon(level, DEFCON_NO_NEW_NICKS);
else if (operation == "nomlockchanges") AddDefCon(level, DEFCON_NO_MLOCK_CHANGE);
else if (operation == "forcechanmodes") AddDefCon(level, DEFCON_FORCE_CHAN_MODES);
else if (operation == "reducedsessions") AddDefCon(level, DEFCON_REDUCE_SESSION);
else if (operation == "nonewclients") AddDefCon(level, DEFCON_NO_NEW_CLIENTS);
else if (operation == "operonly") AddDefCon(level, DEFCON_OPER_ONLY);
else if (operation == "silentoperonly") AddDefCon(level, DEFCON_SILENT_OPER_ONLY);
else if (operation == "akillnewclients") AddDefCon(level, DEFCON_AKILL_NEW_CLIENTS);
else if (operation == "nonewmemos") AddDefCon(level, DEFCON_NO_NEW_MEMOS);
}
}
DefCon[5] = 0; /* DefCon level 5 is always normal operation */
for (defconCount = 1; defconCount <= 5; defconCount++) { /* Check any defcon needed settings */
if (DefCon[defconCount] & DEFCON_REDUCE_SESSION) {
/* Check any defcon needed settings */
for (defconCount = 1; defconCount <= 5; defconCount++)
{
if (CheckDefCon(defconCount, DEFCON_REDUCE_SESSION))
{
CHECK(DefConSessionLimit);
}
if (DefCon[defconCount] & DEFCON_AKILL_NEW_CLIENTS) {
if (CheckDefCon(defconCount, DEFCON_AKILL_NEW_CLIENTS))
{
CHECK(DefConAKILL);
CHECK(DefConAkillReason);
}
if (DefCon[defconCount] & DEFCON_FORCE_CHAN_MODES) {
if (CheckDefCon(defconCount, DEFCON_FORCE_CHAN_MODES))
{
CHECK(DefConChanModes);
}
}
-6
View File
@@ -41,12 +41,6 @@ class CommandCSRegister : public Command
return MOD_CONT;
}
if (checkDefCon(DEFCON_NO_NEW_CHANNELS))
{
notice_lang(s_ChanServ, u, OPER_DEFCON_DENIED);
return MOD_CONT;
}
if (*chan == '&')
notice_lang(s_ChanServ, u, CHAN_REGISTER_NOT_LOCAL);
else if (*chan != '#')
-5
View File
@@ -193,11 +193,6 @@ class CommandCSSet : public Command
ChannelMode *cm;
ChannelModeParam *cmp;
if (checkDefCon(DEFCON_NO_MLOCK_CHANGE)) {
notice_lang(s_ChanServ, u, OPER_DEFCON_DENIED);
return MOD_CONT;
}
ci->ClearMLock();
if (ModeManager::FindChannelModeByName(CMODE_REGISTERED))
-5
View File
@@ -33,11 +33,6 @@ class CommandMSSendAll : public Command
notice_lang(s_MemoServ, u, MEMO_SEND_DISABLED);
return MOD_CONT;
}
else if (checkDefCon(DEFCON_NO_NEW_MEMOS))
{
notice_lang(s_MemoServ, u, OPER_DEFCON_DENIED);
return MOD_CONT;
}
for (i = 0; i < 1024; ++i)
{
-5
View File
@@ -33,11 +33,6 @@ class CommandMSStaff : public Command
notice_lang(s_MemoServ, u, MEMO_SEND_DISABLED);
return MOD_CONT;
}
else if (checkDefCon(DEFCON_NO_NEW_MEMOS))
{
notice_lang(s_MemoServ, u, OPER_DEFCON_DENIED);
return MOD_CONT;
}
for (i = 0; i < 1024; ++i)
{
-5
View File
@@ -43,11 +43,6 @@ class CommandNSGroup : public Command
notice_lang(s_NickServ, u, NICK_GROUP_DISABLED);
return MOD_CONT;
}
if (checkDefCon(DEFCON_NO_NEW_NICKS))
{
notice_lang(s_NickServ, u, OPER_DEFCON_DENIED);
return MOD_CONT;
}
if (!ircdproto->IsNickValid(u->nick))
{
-6
View File
@@ -201,12 +201,6 @@ class CommandNSRegister : public CommandNSConfirm
return MOD_CONT;
}
if (checkDefCon(DEFCON_NO_NEW_NICKS))
{
notice_lang(s_NickServ, u, OPER_DEFCON_DENIED);
return MOD_CONT;
}
if (!is_oper(u) && NickRegDelay && time(NULL) - u->my_signon < NickRegDelay)
{
notice_lang(s_NickServ, u, NICK_REG_DELAY, NickRegDelay);
+419 -17
View File
@@ -16,6 +16,44 @@
#include "module.h"
void defcon_sendlvls(User *u);
void runDefCon();
void defconParseModeString(const char *str);
void resetDefCon(int level);
static char *defconReverseModes(const char *modes);
class DefConTimeout;
static DefConTimeout *timeout;
class DefConTimeout : public Timer
{
int level;
public:
DefConTimeout(int newlevel) : Timer(DefConTimeOut), level(newlevel) { }
void Tick(time_t)
{
if (DefConLevel != level)
{
DefConLevel = level;
FOREACH_MOD(I_OnDefconLevel, OnDefconLevel(level));
alog("Defcon level timeout, returning to lvl %d", level);
ircdproto->SendGlobops(s_OperServ, getstring(OPER_DEFCON_WALL), s_OperServ, level);
if (GlobalOnDefcon)
{
if (DefConOffMessage)
oper_global(NULL, "%s", DefConOffMessage);
else
oper_global(NULL, getstring(DEFCON_GLOBAL), DefConLevel);
if (GlobalOnDefconMore && !DefConOffMessage)
oper_global(NULL, "%s", DefconMessage);
}
runDefCon();
}
}
};
class CommandOSDEFCON : public Command
{
@@ -30,12 +68,6 @@ class CommandOSDEFCON : public Command
int newLevel = 0;
const char *langglobal = getstring(DEFCON_GLOBAL);
if (!DefConLevel) /* If we dont have a .conf setting! */
{
notice_lang(s_OperServ, u, OPER_DEFCON_NO_CONF);
return MOD_CONT;
}
if (!lvl)
{
notice_lang(s_OperServ, u, OPER_DEFCON_CHANGED, DefConLevel);
@@ -52,7 +84,15 @@ class CommandOSDEFCON : public Command
FOREACH_MOD(I_OnDefconLevel, OnDefconLevel(newLevel));
DefContimer = time(NULL);
if (timeout)
{
TimerManager::DelTimer(timeout);
timeout = NULL;
}
if (DefConTimeOut)
timeout = new DefConTimeout(5);
notice_lang(s_OperServ, u, OPER_DEFCON_CHANGED, DefConLevel);
defcon_sendlvls(u);
alog("Defcon level changed to %d by Oper %s", newLevel, u->nick);
@@ -97,12 +137,209 @@ class OSDEFCON : public Module
this->SetVersion("$Id$");
this->SetType(CORE);
if (!DefConLevel)
{
throw ModuleException("Invalid configuration settings");
}
Implementation i[] = { I_OnPreUserConnect, I_OnChannelModeSet, I_OnChannelModeUnset, I_OnPreCommandRun, I_OnPreCommand, I_OnUserConnect, I_OnChannelModeAdd, I_OnChannelCreate };
ModuleManager::Attach(i, this, 8);
this->AddCommand(OPERSERV, new CommandOSDEFCON());
defconParseModeString(DefConChanModes);
}
void OperServHelp(User *u)
{
notice_lang(s_OperServ, u, OPER_HELP_CMD_DEFCON);
}
EventReturn OnPreUserConnect(User *u)
{
std::string mask;
if (u && is_sync(u->server) && CheckDefCon(DEFCON_AKILL_NEW_CLIENTS) && !is_ulined(u->server->name))
{
if (CheckDefCon(DEFCON_AKILL_NEW_CLIENTS))
{
mask = "*@" + std::string(u->host);
alog("DEFCON: adding akill for %s", mask.c_str());
add_akill(NULL, mask.c_str(), s_OperServ,
time(NULL) + DefConAKILL,
DefConAkillReason ? DefConAkillReason :
"DEFCON AKILL");
}
if (CheckDefCon(DEFCON_NO_NEW_CLIENTS) || CheckDefCon(DEFCON_AKILL_NEW_CLIENTS))
kill_user(s_OperServ, u->nick, DefConAkillReason);
return EVENT_STOP;
}
return EVENT_CONTINUE;
}
void OnChannelModeSet(Channel *c, ChannelModeName Name)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(Name);
if (CheckDefCon(DEFCON_FORCE_CHAN_MODES) && cm && DefConModesCI.HasMLock(Name, false))
{
c->RemoveMode(Name);
ircdproto->SendMode(findbot(s_OperServ), c->name, "-%c", cm->ModeChar);
}
}
void OnChannelModeUnset(Channel *c, ChannelModeName Name)
{
ChannelMode *cm = ModeManager::FindChannelModeByName(Name);
if (CheckDefCon(DEFCON_FORCE_CHAN_MODES) && cm && DefConModesCI.HasMLock(Name, true))
{
std::string param;
DefConModesCI.GetParam(Name, &param);
c->SetMode(Name);
std::string buf = "+" + std::string(&cm->ModeChar);
if (!param.empty())
buf += " " + param;
ircdproto->SendMode(findbot(s_OperServ), c->name, buf.c_str());
}
}
EventReturn OnPreCommandRun(const char *service, User *u, const char *cmd, Command *c)
{
if (!c)
{
if (CheckDefCon(DEFCON_SILENT_OPER_ONLY) && !is_oper(u))
return EVENT_STOP;
}
if ((CheckDefCon(DEFCON_OPER_ONLY) || CheckDefCon(DEFCON_SILENT_OPER_ONLY)) && !is_oper(u))
{
if (!CheckDefCon(DEFCON_SILENT_OPER_ONLY))
{
notice_lang(service, u, OPER_DEFCON_DENIED);
}
return EVENT_STOP;
}
return EVENT_CONTINUE;
}
EventReturn OnPreCommand(User *u, const std::string &service, const ci::string &command, const std::vector<ci::string> &params)
{
if (service == s_NickServ)
{
if (command == "SET")
{
if (!params.empty() && params[0] == "MLOCK")
{
if (CheckDefCon(DEFCON_NO_MLOCK_CHANGE))
{
notice_lang(s_ChanServ, u, OPER_DEFCON_DENIED);
return EVENT_STOP;
}
}
}
else if (command == "REGISTER" || command == "GROUP")
{
if (CheckDefCon(DEFCON_NO_NEW_NICKS))
{
notice_lang(s_NickServ, u, OPER_DEFCON_DENIED);
return EVENT_STOP;
}
}
}
else if (service == s_ChanServ)
{
if (command == "REGISTER")
{
if (CheckDefCon(DEFCON_NO_NEW_CHANNELS))
{
notice_lang(s_ChanServ, u, OPER_DEFCON_DENIED);
return EVENT_STOP;
}
}
}
else if (service == s_MemoServ)
{
if (command == "SEND" || command == "SENDALL")
{
if (CheckDefCon(DEFCON_NO_NEW_MEMOS))
{
notice_lang(s_MemoServ, u, OPER_DEFCON_DENIED);
return EVENT_STOP;
}
}
}
return EVENT_CONTINUE;
}
void OnUserConnect(User *u)
{
Session *session = findsession(u->host);
Exception *exception = find_hostip_exception(u->host, u->hostip);
if (CheckDefCon(DEFCON_REDUCE_SESSION) && !exception)
{
if (session && session->count > DefConSessionLimit)
{
if (SessionLimitExceeded)
ircdproto->SendMessage(findbot(s_OperServ), u->nick, SessionLimitExceeded, u->host);
if (SessionLimitDetailsLoc)
ircdproto->SendMessage(findbot(s_OperServ), u->nick, "%s", SessionLimitDetailsLoc);
kill_user(s_OperServ, u->nick, "Session limit exceeded");
session->hits++;
if (MaxSessionKill && session->hits >= MaxSessionKill)
{
char akillmask[BUFSIZE];
snprintf(akillmask, sizeof(akillmask), "*@%s", u->host);
add_akill(NULL, akillmask, s_OperServ, time(NULL) + SessionAutoKillExpiry, "Session limit exceeded");
ircdproto->SendGlobops(s_OperServ, "Added a temporary AKILL for \2%s\2 due to excessive connections", akillmask);
}
}
}
}
void OnChannelModeAdd(ChannelMode *cm)
{
if (DefConChanModes)
{
std::string modes = DefConChanModes;
if (modes.find(cm->ModeChar) != std::string::npos)
{
/* New mode has been added to Anope, check to see if defcon
* requires it
*/
defconParseModeString(DefConChanModes);
}
}
}
void OnChannelCreate(Channel *c)
{
char *myModes;
int ac;
const char **av;
if (CheckDefCon(DEFCON_FORCE_CHAN_MODES))
{
myModes = sstrdup(DefConChanModes);
ac = split_buf(myModes, &av, 1);
ircdproto->SendMode(findbot(s_OperServ), c->name, "%s", DefConChanModes);
chan_set_modes(s_OperServ, c, ac, av, 1);
free(av);
delete [] myModes;
}
}
};
/**
@@ -110,26 +347,191 @@ class OSDEFCON : public Module
**/
void defcon_sendlvls(User *u)
{
if (checkDefCon(DEFCON_NO_NEW_CHANNELS))
if (CheckDefCon(DEFCON_NO_NEW_CHANNELS))
notice_lang(s_OperServ, u, OPER_HELP_DEFCON_NO_NEW_CHANNELS);
if (checkDefCon(DEFCON_NO_NEW_NICKS))
if (CheckDefCon(DEFCON_NO_NEW_NICKS))
notice_lang(s_OperServ, u, OPER_HELP_DEFCON_NO_NEW_NICKS);
if (checkDefCon(DEFCON_NO_MLOCK_CHANGE))
if (CheckDefCon(DEFCON_NO_MLOCK_CHANGE))
notice_lang(s_OperServ, u, OPER_HELP_DEFCON_NO_MLOCK_CHANGE);
if (checkDefCon(DEFCON_FORCE_CHAN_MODES) && DefConChanModes)
if (CheckDefCon(DEFCON_FORCE_CHAN_MODES) && DefConChanModes)
notice_lang(s_OperServ, u, OPER_HELP_DEFCON_FORCE_CHAN_MODES, DefConChanModes);
if (checkDefCon(DEFCON_REDUCE_SESSION))
if (CheckDefCon(DEFCON_REDUCE_SESSION))
notice_lang(s_OperServ, u, OPER_HELP_DEFCON_REDUCE_SESSION, DefConSessionLimit);
if (checkDefCon(DEFCON_NO_NEW_CLIENTS))
if (CheckDefCon(DEFCON_NO_NEW_CLIENTS))
notice_lang(s_OperServ, u, OPER_HELP_DEFCON_NO_NEW_CLIENTS);
if (checkDefCon(DEFCON_OPER_ONLY))
if (CheckDefCon(DEFCON_OPER_ONLY))
notice_lang(s_OperServ, u, OPER_HELP_DEFCON_OPER_ONLY);
if (checkDefCon(DEFCON_SILENT_OPER_ONLY))
if (CheckDefCon(DEFCON_SILENT_OPER_ONLY))
notice_lang(s_OperServ, u, OPER_HELP_DEFCON_SILENT_OPER_ONLY);
if (checkDefCon(DEFCON_AKILL_NEW_CLIENTS))
if (CheckDefCon(DEFCON_AKILL_NEW_CLIENTS))
notice_lang(s_OperServ, u, OPER_HELP_DEFCON_AKILL_NEW_CLIENTS);
if (checkDefCon(DEFCON_NO_NEW_MEMOS))
if (CheckDefCon(DEFCON_NO_NEW_MEMOS))
notice_lang(s_OperServ, u, OPER_HELP_DEFCON_NO_NEW_MEMOS);
}
void runDefCon()
{
char *newmodes;
if (CheckDefCon(DEFCON_FORCE_CHAN_MODES))
{
if (DefConChanModes && !DefConModesSet)
{
if (DefConChanModes[0] == '+' || DefConChanModes[0] == '-')
{
alog("DEFCON: setting %s on all chan's", DefConChanModes);
DefConModesSet = 1;
do_mass_mode(DefConChanModes);
}
}
}
else
{
if (DefConChanModes && (DefConModesSet != 0))
{
if (DefConChanModes[0] == '+' || DefConChanModes[0] == '-')
{
DefConModesSet = 0;
if ((newmodes = defconReverseModes(DefConChanModes)))
{
alog("DEFCON: setting %s on all chan's", newmodes);
do_mass_mode(newmodes);
delete [] newmodes;
}
}
}
}
}
/* Parse the defcon mlock mode string and set the correct global vars.
*
* @param str mode string to parse
* @return 1 if accepted, 0 if failed
*/
void defconParseModeString(const char *str)
{
int add = -1; /* 1 if adding, 0 if deleting, -1 if neither */
unsigned char mode;
ChannelMode *cm;
ChannelModeParam *cmp;
std::string modes, param;
if (!str)
return;
spacesepstream ss(str);
DefConModesCI.ClearMLock();
ss.GetToken(modes);
/* Loop while there are modes to set */
for (unsigned i = 0; i < modes.size(); ++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->CanSet(NULL))
{
alog("DefConChanModes mode character '%c' cannot be locked", mode);
continue;
}
else if (add)
{
DefConModesCI.SetMLock(cm->Name, true);
DefConModesCI.RemoveMLock(cm->Name, false);
if (cm->Type == MODE_PARAM)
{
cmp = static_cast<ChannelModeParam *>(cm);
if (!ss.GetToken(param))
{
alog("DefConChanModes mode character '%c' has no parameter while one is expected", mode);
continue;
}
if (!cmp->IsValid(param.c_str()))
continue;
DefConModesCI.SetParam(cmp->Name, param);
}
}
else
{
DefConModesCI.RemoveMLock(cm->Name, true);
if (DefConModesCI.HasMLock(cm->Name, true))
{
DefConModesCI.RemoveMLock(cm->Name, true);
if (cm->Type == MODE_PARAM)
{
cmp = static_cast<ChannelModeParam *>(cm);
DefConModesCI.UnsetParam(cmp->Name);
}
}
}
}
}
if ((cm = ModeManager::FindChannelModeByName(CMODE_REDIRECT)))
{
/* We can't mlock +L if +l is not mlocked as well. */
if (DefConModesCI.HasMLock(cm->Name, true) && !DefConModesCI.HasMLock(CMODE_LIMIT, true))
{
DefConModesCI.RemoveMLock(CMODE_REDIRECT, true);
DefConModesCI.UnsetParam(CMODE_REDIRECT);
alog("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)))
{
if (DefConModesCI.HasMLock(cm->Name, true) && !DefConModesCI.HasMLock(CMODE_INVITE, true))
{
DefConModesCI.RemoveMLock(CMODE_NOKNOCK, true);
alog("DefConChanModes must lock mode +i as well to lock mode +K");
}
}
}
static char *defconReverseModes(const char *modes)
{
char *newmodes = NULL;
unsigned i = 0;
if (!modes) {
return NULL;
}
if (!(newmodes = new char[strlen(modes) + 1])) {
return NULL;
}
for (i = 0; i < strlen(modes); i++) {
if (modes[i] == '+')
newmodes[i] = '-';
else if (modes[i] == '-')
newmodes[i] = '+';
else
newmodes[i] = modes[i];
}
newmodes[i] = '\0';
return newmodes;
}
MODULE_INIT(OSDEFCON)
-8
View File
@@ -406,14 +406,6 @@ int init_secondary(int ac, char **av)
/* Parse all remaining command-line options. */
parse_options(ac, av);
/* Parse the defcon mode string if needed */
if (DefConLevel) {
if (!defconParseModeString(DefConChanModes)) {
fprintf(stderr,
"services.conf: The given DefConChanModes mode string was incorrect (see log for exact errors)\n");
return -1;
}
}
#ifndef _WIN32
if (!nofork) {
if ((i = fork()) < 0) {
-7
View File
@@ -366,7 +366,6 @@ int main(int ac, char **av, char **envp)
time_t last_update; /* When did we last update the databases? */
time_t last_expire; /* When did we last expire nicks/channels? */
time_t last_check; /* When did we last check timeouts? */
time_t last_DefCon; /* When was DefCon last checked? */
int i;
char *progname;
@@ -429,7 +428,6 @@ int main(int ac, char **av, char **envp)
last_update = time(NULL);
last_expire = time(NULL);
last_check = time(NULL);
last_DefCon = time(NULL);
started = 1;
@@ -481,11 +479,6 @@ int main(int ac, char **av, char **envp)
last_update = t;
}
if ((DefConTimeOut) && (t - last_DefCon >= DefConTimeOut)) {
resetDefCon(5);
last_DefCon = t;
}
if (delayed_quit)
break;
+2 -4
View File
@@ -201,9 +201,6 @@ void memo_send(User * u, const char *name, const char *text, int z)
if (readonly) {
notice_lang(s_MemoServ, u, MEMO_SEND_DISABLED);
} else if (checkDefCon(DEFCON_NO_NEW_MEMOS)) {
notice_lang(s_MemoServ, u, OPER_DEFCON_DENIED);
return;
} else if (!text) {
if (z == 0)
syntax_error(s_MemoServ, u, "SEND", MEMO_SEND_SYNTAX);
@@ -388,7 +385,8 @@ void rsend_notify(User * u, Memo * m, const char *chan)
const char *fmt;
/* Only send receipt if memos are allowed */
if ((!readonly) && (!checkDefCon(DEFCON_NO_NEW_MEMOS))) {
if ((!readonly))
{
/* Get nick alias for sender */
na = findnick(m->sender);
+1
View File
@@ -10,6 +10,7 @@
*/
#include "services.h"
#include "modules.h"
std::map<char, UserMode *> ModeManager::UserModesByChar;
std::map<UserModeName, UserMode *> ModeManager::UserModesByName;
-3
View File
@@ -822,9 +822,6 @@ void req_send_memos(User *u, char *vIdent, char *vHost)
char host[BUFSIZE];
std::list<std::pair<std::string, std::string> >::iterator it;
if (checkDefCon(DEFCON_NO_NEW_MEMOS))
return;
if (vIdent)
snprintf(host, sizeof(host), "%s@%s", vIdent, vHost);
else
+36 -223
View File
@@ -31,12 +31,8 @@ static void free_sqline_entry(SList * slist, void *item);
static int is_szline_entry_equal(SList * slist, void *item1, void *item2);
static void free_szline_entry(SList * slist, void *item);
time_t DefContimer;
std::vector<std::bitset<32> > DefCon;
int DefConModesSet = 0;
char *defconReverseModes(const char *modes);
uint32 DefConModesOn; /* Modes to be enabled during DefCon */
uint32 DefConModesOff; /* Modes to be disabled during DefCon */
ChannelInfo DefConModesCI; /* ChannelInfo containg params for locked modes
* during DefCon; I would've done this nicer if i
* could, but all damn mode functions require a
@@ -495,14 +491,6 @@ int check_akill(const char *nick, const char *username, const char *host,
int i;
Akill *ak;
/**
* If DefCon is set to NO new users - kill the user ;).
**/
if (checkDefCon(DEFCON_NO_NEW_CLIENTS)) {
kill_user(s_OperServ, nick, DefConAkillReason);
return 1;
}
if (akills.count == 0)
return 0;
@@ -1173,217 +1161,42 @@ static int is_szline_entry_equal(SList * slist, void *item1, void *item2)
/*************************************************************************/
/**
* Returns 1 if the passed level is part of the CURRENT defcon, else 0 is returned
**/
int checkDefCon(int level)
{
return DefCon[DefConLevel] & level;
}
/**
* Automaticaly re-set the DefCon level if the time limit has expired.
**/
void resetDefCon(int level)
{
char strLevel[5];
snprintf(strLevel, 4, "%d", level);
if (DefConLevel != level) {
if ((DefContimer)
&& (time(NULL) - DefContimer >= DefConTimeOut)) {
DefConLevel = level;
FOREACH_MOD(I_OnDefconLevel, OnDefconLevel(strLevel));
alog("Defcon level timeout, returning to lvl %d", level);
ircdproto->SendGlobops(s_OperServ,
getstring(OPER_DEFCON_WALL),
s_OperServ, level);
if (GlobalOnDefcon) {
if (DefConOffMessage) {
oper_global(NULL, "%s", DefConOffMessage);
} else {
oper_global(NULL, getstring(DEFCON_GLOBAL),
DefConLevel);
}
}
if (GlobalOnDefconMore && !DefConOffMessage) {
oper_global(NULL, "%s", DefconMessage);
}
runDefCon();
}
}
}
/**
* Run DefCon level specific Functions.
**/
void runDefCon()
{
char *newmodes;
if (checkDefCon(DEFCON_FORCE_CHAN_MODES)) {
if (DefConChanModes && !DefConModesSet) {
if (DefConChanModes[0] == '+' || DefConChanModes[0] == '-') {
alog("DEFCON: setting %s on all chan's", DefConChanModes);
DefConModesSet = 1;
do_mass_mode(DefConChanModes);
}
}
} else {
if (DefConChanModes && (DefConModesSet != 0)) {
if (DefConChanModes[0] == '+' || DefConChanModes[0] == '-') {
DefConModesSet = 0;
if ((newmodes = defconReverseModes(DefConChanModes))) {
alog("DEFCON: setting %s on all chan's", newmodes);
do_mass_mode(newmodes);
delete [] newmodes;
}
}
}
}
}
/**
* Reverse the mode string, used for remove DEFCON chan modes.
**/
char *defconReverseModes(const char *modes)
{
char *newmodes = NULL;
unsigned i = 0;
if (!modes) {
return NULL;
}
if (!(newmodes = new char[strlen(modes) + 1])) {
return NULL;
}
for (i = 0; i < strlen(modes); i++) {
if (modes[i] == '+')
newmodes[i] = '-';
else if (modes[i] == '-')
newmodes[i] = '+';
else
newmodes[i] = modes[i];
}
newmodes[i] = '\0';
return newmodes;
}
/* Parse the defcon mlock mode string and set the correct global vars.
*
* @param str mode string to parse
* @return 1 if accepted, 0 if failed
/** Check if a certain defcon option is currently in affect
* @param Level The level
* @return true and false
*/
int defconParseModeString(const char *str)
bool CheckDefCon(DefconLevel Level)
{
int add = -1; /* 1 if adding, 0 if deleting, -1 if neither */
unsigned char mode;
ChannelMode *cm;
ChannelModeParam *cmp;
char *str_copy = sstrdup(str); /* We need this copy as str is const -GD */
char *param; /* Store parameters during mode parsing */
/* Reinitialize everything */
DefConModesOn = 0;
DefConModesOff = 0;
/* Initialize strtok() internal buffer */
strtok(str_copy, " ");
/* Loop while there are modes to set */
while ((mode = *str++) && (mode != ' ')) {
switch (mode) {
case '+':
add = 1;
continue;
case '-':
add = 0;
continue;
default:
if (add < 0)
continue;
}
if ((cm = ModeManager::FindChannelModeByChar(mode)))
{
if (!cm->CanSet(NULL))
{
alog("DefConCHanModes mode character '%c' cannot be locked", mode);
delete [] str_copy;
return 0;
}
else if (add)
{
DefConModesCI.SetMLock(cm->Name, true);
DefConModesCI.RemoveMLock(cm->Name, false);
if (cm->Type == MODE_PARAM)
{
cmp = static_cast<ChannelModeParam *>(cm);
if (!(param = strtok(NULL, " ")))
{
alog("DefConChanModes mode character '%c' has no parameter while one is expected", mode);
delete [] str_copy;
return 0;
}
if (!cmp->IsValid(param))
continue;
DefConModesCI.SetParam(cmp->Name, param);
}
}
else
{
DefConModesCI.RemoveMLock(cm->Name, true);
if (DefConModesCI.HasMLock(cm->Name, true))
{
DefConModesCI.RemoveMLock(cm->Name, true);
if (cm->Type == MODE_PARAM)
{
cmp = static_cast<ChannelModeParam *>(cm);
DefConModesCI.UnsetParam(cmp->Name);
}
}
}
}
else
{
alog("DefConChanModes unknown mode character '%c'", mode);
delete [] str_copy;
return 0;
}
} /* while (*param) */
delete [] str_copy;
if ((cm = ModeManager::FindChannelModeByName(CMODE_REDIRECT)))
{
/* We can't mlock +L if +l is not mlocked as well. */
if (DefConModesCI.HasMLock(cm->Name, true) && !DefConModesCI.HasMLock(CMODE_LIMIT, true))
{
DefConModesCI.RemoveMLock(CMODE_REDIRECT, true);
DefConModesCI.UnsetParam(CMODE_REDIRECT);
alog("DefConChanModes must lock mode +l as well to lock mode +L");
return 0;
}
}
/* 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)))
{
if (DefConModesCI.HasMLock(cm->Name, true) && !DefConModesCI.HasMLock(CMODE_INVITE, true))
{
DefConModesCI.RemoveMLock(CMODE_NOKNOCK, true);
alog("DefConChanModes must lock mode +i as well to lock mode +K");
return 0;
}
}
/* Everything is set fine, return 1 */
return 1;
if (DefConLevel)
return DefCon[DefConLevel][(size_t)Level];
return false;
}
/** Check if a certain defcon option is in a certain defcon level
* @param level The defcon level
* @param Level The defcon level name
* @return true or false
*/
bool CheckDefCon(int level, DefconLevel Level)
{
return DefCon[level][(size_t)Level];
}
/** Add a defcon level option to a defcon level
* @param level The defcon level
* @param Level The defcon level option
*/
void AddDefCon(int level, DefconLevel Level)
{
DefCon[level][(size_t)Level] = true;
}
/** Remove a defcon level option from a defcon level
* @param level The defcon level
* @param Level The defcon level option
*/
void DelDefCon(int level, DefconLevel Level)
{
DefCon[level][(size_t)Level] = false;
}
/*************************************************************************/
+1 -6
View File
@@ -138,12 +138,7 @@ int add_session(const char *nick, const char *host, char *hostip)
if (session) {
exception = find_hostip_exception(host, hostip);
if (checkDefCon(DEFCON_REDUCE_SESSION)) {
sessionlimit =
exception ? exception->limit : DefConSessionLimit;
} else {
sessionlimit = exception ? exception->limit : DefSessionLimit;
}
sessionlimit = exception ? exception->limit : DefSessionLimit;
if (sessionlimit != 0 && session->count >= sessionlimit) {
if (SessionLimitExceeded)
+1 -14
View File
@@ -627,7 +627,6 @@ User *do_nick(const char *source, const char *nick, const char *username, const
NickAlias *old_na; /* Old nick rec */
int nc_changed = 1; /* Did nick core change? */
int status = 0; /* Status to apply */
char mask[USERMAX + HOSTMAX + 2];
char *logrealname;
std::string oldnick; /* stores the old nick of the user, so we can pass it to OnUserNickChange */
@@ -709,22 +708,10 @@ User *do_nick(const char *source, const char *nick, const char *username, const
EventReturn MOD_RESULT;
FOREACH_RESULT(I_OnPreUserConnect, OnPreUserConnect(user));
if (MOD_RESULT == EVENT_STOP)
return;
return NULL;
check_akill(nick, username, host, vhost, ipbuf);
if (is_sync(findserver(servlist, server)) && checkDefCon(DEFCON_AKILL_NEW_CLIENTS) && !is_ulined(server))
{
strlcpy(mask, "*@", sizeof(mask));
strlcat(mask, host, sizeof(mask));
alog("DEFCON: adding akill for %s", mask);
add_akill(NULL, mask, s_OperServ,
time(NULL) + DefConAKILL,
DefConAkillReason ? DefConAkillReason :
"DEFCON AKILL");
check_akill(nick, username, host, vhost, ipbuf);
}
if (ircd->sgline)
check_sgline(nick, realname);