/***********************************************************************
X3 ChangeLog
+2006-07-31 Neil Spierling <sirvulcan@gmail.com>
+
+ * x3.conf.example: Added new Defcon system settings
+
+ * doc/DEFCON: Anope's Defcon doc adapted for X3.
+
+ * src/chanserv.c: Block mode changes and channel registrations if
+ required.
+
+ * src/mod-memoserv.c: Block new memos if required.
+
+ * src/nickserv.c: Block nick registrations if required.
+
+ * src/opserv.c: Added in defcon system, uses some of the anope code.
+ Most tho is from scratch.
+
+ * src/opserv.h: Defcon declerations.
+
+ * src/opserv.help: Added DEFCON entry.
+
+ * src/proto-p10.c: If required gline new clients, also if required
+ kill new clients.
+
2006-07-29 Alex Schumann <rubin@afternet.org>
* configure.in, Makefile.in, src/Makefile.in, tools/tre_install.sh,
--- /dev/null
+X3 DefCon
+------------
+
+1) Introduction
+2) Installation
+3) Configuration
+4) Usage
+5) Usage Example
+
+1) Introduction
+
+ X3 supports a unique protection mechanism based on the military "Defense
+ Readiness Condition" (DefCon) system. It is based on 5 levels of defense
+ readiness defined as:
+
+ DEFCON5 Normal peacetime readiness
+ DEFCON4 Increased intelligence and security readiness
+ DEFCON3 Increase in force readiness
+ DEFCON2 Further increase in force readiness
+ DEFCON1 Maximum force readiness.
+
+ These are configurable levels that mandates what actions X3 should
+ take in case of emergency and change in readiness status.
+
+ It is used to prevent abuse to both Services, and the ircd on which they
+ are running. Also to protect the users, primarily in the event of Clones
+ and/or FloodBOT attacks.
+
+2) Installation
+
+ The DefCon system is part of O3,
+
+ The DefCon system has to be configured on your x3.conf file to
+ be enabled.
+
+ Make sure you restart X3 after changing the DefCon configuration
+ directives.
+
+3) Configuration
+
+ Pre-defined DefCon actions:
+
+ No new channel registrations 1
+ No New Nick Registrations 2
+ No channel Mode changes 4
+ Force Chan Mode 8
+ Use Reduced Session Limit 16
+ KILL any new clients trying to connect 32
+ Services will ignore everyone but opers 64
+ Services will silently ignore everyone but opers 128
+ GLINE all new clients trying to connect 256
+ No new memos sent to block MemoServ attacks 512
+
+ These are the values used to determine each defcon setting, are set via:
+
+ "DefCon1 "XX";
+ "DefCon2 "XX";
+ "DefCon3 "XX";
+ "DefCon4 "XX";
+
+ To set the desired value, you simply add the value of the numbers together
+ and place that as your DefCon# setting. For instance:
+
+ Say you wish to set:
+
+ No Channel Registrations, No Nickname Registrations and Services Ignoring
+ everyone except for Operators. You would do this by:
+
+ 1 + 2 + 128 (Each value listed above is added together)
+ Giving: 131
+
+ You would then place this as which ever Defcon setting you want:
+
+ "DefCon1" "131";
+
+ The recommended default values are safe to use on any network.
+
+4) Usage
+
+ X3 starts up in DEFCON5 (normal readiness) by default, this is configurable.
+ To change the Defcon level in action use:
+
+ /msg O3 DEFCON 1|2|3|4|5
+
+5) Usage Example
+
+ Place the network on DEFCON3:
+
+ /msg O3 DEFCON 3
+
+ <O3> DefCon is at level 3 and enforcing:
+ <O3> No Channel Registrations
+ <O3> No Nickname/Account Registrations
+ <O3> No ChanServ SET MODE Changes
+ <O3> Forcing Channel Mode(s): +r
+ <O3> Forcing Reduced Session: 2
+ <O3> Allowing Services Communication With Opers Only AND Silently Ignoring Regular Users
+ <Global> Network DefCon level has changed to level 3
+ <Global> SiRVulcaN is changing the DefCon level to 3
+
+ Note that the last message is sent to Opers only.
+
+ Restore normal readiness:
+
+ /msg O3 DEFCON 5
+
+ <O3> DefCon is at level 5 and allowing everything
+ <Global> Network DefCon level has changed to level 5
+ <Global> SiRVulcaN is changing the DefCon level to 5
+
+ Note that the last message is sent to Opers only.
+
+ Listing The Currently Set DefCon Settings:
+
+ /msg O3 DEFCON
+
+ <O3> DefCon is at level 3 and enforcing:
+ <O3> No Channel Registrations
+ <O3> No Nickname/Account Registrations
+ <O3> No ChanServ SET MODE Changes
+ <O3> Forcing Channel Mode(s): +r
+ <O3> Forcing Reduced Session: 2
+ <O3> Allowing Services Communication With Opers Only AND Silently Ignoring Regular Users
+
/* Other things */
{ "CSMSG_EVENT_SEARCH_RESULTS", "$bChannel Events for %s$b" },
{ "CSMSG_LAST_INVALID", "Invalid argument. must be 1-200" },
+ { "CSMSG_DEFCON_NO_NEW_CHANNELS", "You cannot register new channels at this time, please try again soon." },
+ { "CSMSG_DEFCON_NO_MODE_CHANGE", "You cannot change the MODE at this time, please try again soon." },
{ NULL, NULL }
};
struct do_not_register *dnr;
unsigned int n;
+ if (checkDefCon(DEFCON_NO_NEW_CHANNELS) && !IsOper(user)) {
+ reply("CSMSG_DEFCON_NO_NEW_CHANNELS");
+ return 0;
+ }
if(channel)
{
if(argc < 2)
{
+ if (checkDefCon(DEFCON_NO_MODE_CHANGE) && !IsOper(user)) {
+ reply("CSMSG_DEFCON_NO_MODE_CHANGE");
+ return 0;
+ }
+
change = &channel->channel_info->modes;
if(change->modes_set || change->modes_clear) {
modcmd_chanmode_announce(change);
if(argc > 1)
{
+ if (checkDefCon(DEFCON_NO_MODE_CHANGE) && !IsOper(user)) {
+ reply("CSMSG_DEFCON_NO_MODE_CHANGE");
+ return 0;
+ }
+
if(!check_user_level(channel, user, lvlEnfModes, 1, 0))
{
reply("CSMSG_NO_ACCESS");
#include "conf.h"
#include "modcmd.h"
#include "nickserv.h"
+#include "opserv.h"
#include "saxdb.h"
#include "timeq.h"
{ "MSMSG_LIST_END", "--------------End of Memos--------------" },
{ "MSMSG_BAR", "----------------------------------------"},
+ { "MSMSG_DEFCON_NO_NEW_MEMOS", "You cannot send new memos at this time, please try again soon." },
+
{ NULL, NULL }
};
MEMOSERV_MIN_PARAMS(3);
+ if (checkDefCon(DEFCON_NO_NEW_MEMOS) && !IsOper(user)) {
+ reply("MSMSG_DEFCON_NO_NEW_MEMOS");
+ return 0;
+ }
+
if (!(hi = modcmd_get_handle_info(user, argv[1])))
return 0;
{ "NSMSG_NOT_VALID_FAKEHOST_REGEX", "$b%s$b is not allowed by the admin, consult the valid vhost regex pattern in the config file under nickserv/valid_fakehost_regex." },
{ "CHECKPASS_YES", "Yes." },
{ "CHECKPASS_NO", "No." },
+ { "NSMSG_DEFCON_NO_NEW_NICKS", "You cannot register new %s at this time, please try again soon" },
{ NULL, NULL }
};
char syncpass[MD5_CRYPT_LENGTH];
int no_auth, weblink;
+ if (checkDefCon(DEFCON_NO_NEW_NICKS) && !IsOper(user)) {
+ reply("NSMSG_DEFCON_NO_NEW_NICKS", nickserv_conf.disable_nicks ? "accounts" : "nicknames");
+ return 0;
+ }
+
if (!IsOper(user) && !dict_size(nickserv_handle_dict)) {
/* Require the first handle registered to belong to someone +o. */
reply("NSMSG_REQUIRE_OPER");
#define KEY_OFFLINE "offline"
#define KEY_ROUTINGPLAN "routingplan"
#define KEY_ROUTINGPLAN_OPTIONS "routingplan_options"
+#define KEY_DEFCON1 "DefCon1"
+#define KEY_DEFCON2 "DefCon2"
+#define KEY_DEFCON3 "DefCon3"
+#define KEY_DEFCON4 "DefCon4"
+#define KEY_DEFCON_LEVEL "DefConLevel"
+#define KEY_DEFCON_CHANMODES "DefConChanModes"
+#define KEY_DEFCON_SESSION_LIMIT "DefConSessionLimit"
+#define KEY_DEFCON_TIMEOUT "DefConTimeOut"
+#define KEY_DEFCON_GLOBAL_TARGET "DefConGlobalTarget"
+#define KEY_DEFCON_GLOBAL "GlobalOnDefcon"
+#define KEY_DEFCON_GLOBAL_MORE "GlobalOnDefconMore"
+#define KEY_DEFCON_MESSAGE "DefconMessage"
+#define KEY_DEFCON_OFF_MESSAGE "DefConOffMessage"
+#define KEY_DEFCON_GLINE_DURATION "DefConGlineExpire"
+#define KEY_DEFCON_GLINE_REASON "DefConGlineReason"
/* Routing karma values: */
/* What value we start out with when new servers are added: */
{ "OSMSG_INVALID_REGEX", "Invalid regex: %s: %s (%d)" },
{ "OSMSG_TRACK_DISABLED", "Tracking is not currently compiled into X3" },
{ "OSMSG_MAXUSERS_RESET", "Max clients has been reset to $b%d$b" },
+
+ { "OSMSG_DEFCON_INVALID", "DefCon level %d is invalid, please choose a value between 1 and 5" },
+ { "OSMSG_DEFCON_ALLOWING_ALL", "DefCon is at level 5 and allowing everything" },
+ { "OSMSG_DEFCON_DISALLOWING", "DefCon is at level %d and enforcing:" },
+ { "OSMSG_DEFCON_NO_NEW_CHANNELS", "No Channel Registrations" },
+ { "OSMSG_DEFCON_NO_NEW_NICKS", "No Nickname/Account Registrations" },
+ { "OSMSG_DEFCON_NO_MODE_CHANGE", "No Channel Mode Changes" },
+ { "OSMSG_DEFCON_NO_NEW_CLIENTS", "No New Clients" },
+ { "OSMSG_DEFCON_FORCE_CHANMODES", "Forcing Channel Mode(s): %s" },
+ { "OSMSG_DEFCON_REDUCE_SESSION", "Forcing Reduced Session: %d" },
+ { "OSMSG_DEFCON_OPER_ONLY", "Allowing Services Communication With Opers Only" },
+ { "OSMSG_DEFCON_SILENT_OPER_ONLY", "Allowing Services Communication With Opers Only AND Silently Ignoring Regular Users" },
+ { "OSMSG_DEFCON_GLINE_NEW_CLIENTS", "Glining New Clients" },
+ { "OSMSG_DEFCON_NO_NEW_MEMOS", "Disallowing New Memos" },
+
{ NULL, NULL }
};
#define OPSERV_SYNTAX() svccmd_send_help_brief(user, opserv, cmd)
+int DefConLevel = 5;
+int DefCon[6];
+int DefConTimeOut;
+int GlobalOnDefcon = 0;
+int GlobalOnDefconMore = 0;
+int DefConGlineExpire;
+int DefConModesSet = 0;
+int DefConGlobalTarget = 3;
+unsigned int DefConSessionLimit;
+char *DefConChanModes;
+char *DefConGlineReason;
+char *DefConMessage;
+char *DefConOffMessage;
+
extern void add_track_user(struct userNode *user);
typedef int (*discrim_search_func)(struct userNode *match, void *extra);
#define opserv_alert(format...) do { if (opserv_conf.alert_channel) send_channel_notice(opserv_conf.alert_channel , opserv , ## format); } while (0)
+char *defconReverseModes(const char *modes)
+{
+ char *newmodes = NULL;
+ unsigned int i = 0;
+ if (!modes) {
+ return NULL;
+ }
+ if (!(newmodes = malloc(sizeof(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;
+}
+
+int checkDefCon(int level)
+{
+ return DefCon[DefConLevel] & level;
+}
+
+void showDefConSettings(struct userNode *user, struct svccmd *cmd)
+{
+ if (DefConLevel == 5) {
+ reply("OSMSG_DEFCON_ALLOWING_ALL");
+ return;
+ } else
+ reply("OSMSG_DEFCON_DISALLOWING", DefConLevel);
+
+ if (checkDefCon(DEFCON_NO_NEW_CHANNELS))
+ reply("OSMSG_DEFCON_NO_NEW_CHANNELS");
+
+ if (checkDefCon(DEFCON_NO_NEW_NICKS))
+ reply("OSMSG_DEFCON_NO_NEW_NICKS");
+
+ if (checkDefCon(DEFCON_NO_MODE_CHANGE))
+ reply("OSMSG_DEFCON_NO_MODE_CHANGE");
+
+ if (checkDefCon(DEFCON_FORCE_CHAN_MODES) && (DefConChanModes))
+ reply("OSMSG_DEFCON_FORCE_CHANMODES", DefConChanModes);
+
+ if (checkDefCon(DEFCON_REDUCE_SESSION))
+ reply("OSMSG_DEFCON_REDUCE_SESSION", DefConSessionLimit);
+
+ if (checkDefCon(DEFCON_NO_NEW_CLIENTS))
+ reply("OSMSG_DEFCON_NO_NEW_CLIENTS");
+
+ if (checkDefCon(DEFCON_OPER_ONLY))
+ reply("OSMSG_DEFCON_OPER_ONLY");
+
+ if (checkDefCon(DEFCON_SILENT_OPER_ONLY))
+ reply("OSMSG_DEFCON_SILENT_OPER_ONLY");
+
+ if (checkDefCon(DEFCON_GLINE_NEW_CLIENTS))
+ reply("OSMSG_DEFCON_GLINE_NEW_CLIENTS");
+
+ if (checkDefCon(DEFCON_NO_NEW_MEMOS))
+ reply("OSMSG_DEFCON_NO_NEW_MEMOS");
+
+ return;
+}
+
+void do_mass_mode(char *modes)
+{
+ dict_iterator_t it;
+
+ if (!modes)
+ return;
+
+ for (it = dict_first(channels); it; it = iter_next(it)) {
+ struct chanNode *chan = iter_data(it);
+
+ irc_mode(opserv, chan, modes);
+ }
+
+}
+
+void DefConProcess(struct userNode *user)
+{
+ char *newmodes;
+ long targets;
+
+ if (DefConGlobalTarget == 1)
+ targets = MESSAGE_RECIPIENT_LUSERS;
+ else if (DefConGlobalTarget == 2)
+ targets = MESSAGE_RECIPIENT_CHANNELS;
+ else
+ targets = MESSAGE_RECIPIENT_ALL;
+
+ if (GlobalOnDefcon) {
+ char *globalmsg;
+ globalmsg = alloca(44);
+ sprintf(globalmsg, "Network DefCon level has changed to level %d", DefConLevel);
+ global_message(targets, globalmsg);
+ }
+
+ if (GlobalOnDefconMore)
+ global_message(targets, DefConMessage);
+
+ if ((DefConLevel == 5) && !GlobalOnDefconMore && !GlobalOnDefcon)
+ global_message(targets, DefConOffMessage);
+
+ char *opermsg;
+ if (user) {
+ opermsg = alloca(strlen(user->nick) + 35);
+ sprintf(opermsg, "%s is changing the DefCon level to %d", user->nick, DefConLevel);
+ } else {
+ opermsg = alloca(49);
+ sprintf(opermsg, "The DefCon has changed back to level %d (timeout)", DefConLevel);
+ }
+ global_message(MESSAGE_RECIPIENT_OPERS, opermsg);
+
+ if (checkDefCon(DEFCON_FORCE_CHAN_MODES)) {
+ if (DefConChanModes && !DefConModesSet) {
+ if (DefConChanModes[0] == '+' || DefConChanModes[0] == '-') {
+ do_mass_mode(DefConChanModes);
+ DefConModesSet = 1;
+ }
+ }
+ } else {
+ if (DefConChanModes && (DefConModesSet != 0)) {
+ if (DefConChanModes[0] == '+' || DefConChanModes[0] == '-') {
+ if ((newmodes = defconReverseModes(DefConChanModes))) {
+ do_mass_mode(newmodes);
+ free(newmodes);
+ }
+ DefConModesSet = 0;
+ }
+ }
+ }
+
+ return;
+}
+
+void
+defcon_timeout(UNUSED_ARG(void *data))
+{
+ DefConLevel = 5;
+ DefConProcess(NULL);
+}
+
+static MODCMD_FUNC(cmd_defcon)
+{
+ if ((argc < 2) || (atoi(argv[1]) == DefConLevel)) {
+ showDefConSettings(user, cmd);
+ return 1;
+ }
+
+ if ((atoi(argv[1]) < 1) || (atoi(argv[1]) > 5)) {
+ reply("OSMSG_DEFCON_INVALID", atoi(argv[1]));
+ return 0;
+ }
+
+ DefConLevel = atoi(argv[1]);
+ showDefConSettings(user, cmd);
+
+ if (DefConTimeOut > 0) {
+ timeq_del(0, defcon_timeout, NULL, TIMEQ_IGNORE_DATA & TIMEQ_IGNORE_WHEN);
+ timeq_add(now + DefConTimeOut, defcon_timeout, NULL);
+ }
+
+ DefConProcess(user);
+ return 1;
+}
+
/* A lot of these commands are very similar to what ChanServ can do,
* but OpServ can do them even on channels that aren't registered.
*/
}
}
+ if (checkDefCon(DEFCON_NO_NEW_CLIENTS)) {
+ irc_kill(opserv, user, DefConGlineReason);
+ return 0;
+ }
+
/* Only warn or G-line if there's an untrusted max and their IP is sane. */
if (opserv_conf.untrusted_max
&& irc_in_addr_is_valid(user->ip)
&& !irc_in_addr_is_loopback(user->ip)) {
struct trusted_host *th = dict_find(opserv_trusted_hosts, addr, NULL);
unsigned int limit = th ? th->limit : opserv_conf.untrusted_max;
+
+ if (checkDefCon(DEFCON_REDUCE_SESSION) && !th)
+ limit = DefConSessionLimit;
+
if (!limit) {
/* 0 means unlimited hosts */
} else if (ohi->clients.used == limit) {
policer_params_set(pp, "drain-rate", "3");
if ((child = database_get_data(conf_node, KEY_NEW_USER_POLICER, RECDB_OBJECT)))
dict_foreach(child, set_policer_param, pp);
+
+ /* Defcon configuration */
+ DefCon[0] = 0;
+ str = database_get_data(conf_node, KEY_DEFCON1, RECDB_QSTRING);
+ DefCon[1] = str ? atoi(str) : 415;
+ str = database_get_data(conf_node, KEY_DEFCON2, RECDB_QSTRING);
+ DefCon[2] = str ? atoi(str) : 159;
+ str = database_get_data(conf_node, KEY_DEFCON3, RECDB_QSTRING);
+ DefCon[3] = str ? atoi(str) : 31;
+ str = database_get_data(conf_node, KEY_DEFCON4, RECDB_QSTRING);
+ DefCon[4] = str? atoi(str) : 23;
+ DefCon[5] = 0;
+
+ str = database_get_data(conf_node, KEY_DEFCON_LEVEL, RECDB_QSTRING);
+ DefConLevel = str ? atoi(str) : 5;
+
+ str = database_get_data(conf_node, KEY_DEFCON_CHANMODES, RECDB_QSTRING);
+ DefConChanModes = str ? strdup(str) : "+r";
+
+ str = database_get_data(conf_node, KEY_DEFCON_SESSION_LIMIT, RECDB_QSTRING);
+ DefConSessionLimit = str ? atoi(str) : 2;
+
+ str = database_get_data(conf_node, KEY_DEFCON_TIMEOUT, RECDB_QSTRING);
+ DefConTimeOut = str ? ParseInterval(str) : 900;
+
+ str = database_get_data(conf_node, KEY_DEFCON_GLINE_DURATION, RECDB_QSTRING);
+ DefConGlineExpire = str ? ParseInterval(str) : 300;
+
+ str = database_get_data(conf_node, KEY_DEFCON_GLOBAL_TARGET, RECDB_QSTRING);
+ DefConGlobalTarget = str ? atoi(str) : 3;
+
+ str = database_get_data(conf_node, KEY_DEFCON_GLOBAL, RECDB_QSTRING);
+ GlobalOnDefcon = str ? atoi(str) : 0;
+
+ str = database_get_data(conf_node, KEY_DEFCON_GLOBAL_MORE, RECDB_QSTRING);
+ GlobalOnDefconMore = str ? atoi(str) : 0;
+
+ str = database_get_data(conf_node, KEY_DEFCON_MESSAGE, RECDB_QSTRING);
+ DefConMessage = str ? strdup(str) : "Put your message to send your users here. Dont forget to uncomment GlobalOnDefconMore";
+
+ str = database_get_data(conf_node, KEY_DEFCON_OFF_MESSAGE, RECDB_QSTRING);
+ DefConOffMessage = str? strdup(str) : "Services are now back to normal, sorry for any inconvenience";
+
+ str = database_get_data(conf_node, KEY_DEFCON_GLINE_REASON, RECDB_QSTRING);
+ DefConGlineReason = str ? strdup(str) : "This network is currently not accepting connections, please try again later";
}
/* lame way to export opserv_conf value to nickserv.c ... */
opserv_define_func("DELTRUST", cmd_deltrust, 800, 0, 2);
opserv_define_func("DEOP", cmd_deop, 100, 2, 2);
opserv_define_func("DEOPALL", cmd_deopall, 400, 2, 0);
+ opserv_define_func("DEFCON", cmd_defcon, 900, 0, 0);
opserv_define_func("DEHOP", cmd_dehop, 100, 2, 2);
opserv_define_func("DEHOPALL", cmd_dehopall, 400, 2, 0);
opserv_define_func("DEVOICEALL", cmd_devoiceall, 300, 2, 0);
#ifndef _opserv_h
#define _opserv_h
+#define DEFCON_NO_NEW_CHANNELS 1 /* No New Channel Registrations */
+#define DEFCON_NO_NEW_NICKS 2 /* No New Nick Registrations */
+#define DEFCON_NO_MODE_CHANGE 4 /* No SET MODE 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_GLINE_NEW_CLIENTS 256 /* Gline any new clients */
+#define DEFCON_NO_NEW_MEMOS 512 /* No New Memos Sent */
+
+extern int DefCon[6];
+extern int checkDefCon(int level);
+extern void DefConProcess(struct userNode *user);
+extern void defcon_timeout(UNUSED_ARG(void *data));
void init_opserv(const char *nick);
unsigned int gag_create(const char *mask, const char *owner, const char *reason, time_t expires);
int opserv_bad_channel(const char *name);
" $bJUPE$b Create dummy server.",
" $bUNJUPE$b Remove a dummy server.",
" $b$b",
+ " $bDEFCON$b Manipulate the DefCon system.",
" $bREFRESHG$b Refresh the Glines.",
" $bREFRESHS$b Refresh the Shuns.",
" $bSETTIME$b Synchronize time across the network.",
"$uSee Also:$u refreshg, gline, ungline"
);
+"DEFCON" ("/msg $O DEFCON [1|2|3|4|5]",
+ "The defcon system can be used to implement a pre-defined set of restrictions to services useful during an attempted attack on the network. Not specifying a level will cause $O to display the currently set defcon level and options if the level is below 5",
+ "Access level: $b${level/defcon}$b",
+ );
+
"REFRESHG" ("/msg $O REFRESHG [server]",
"Re-issues all GLINES in $b$O's$b database. Usually used for newly joining or desynched servers. If a server mask is specified, the GLINES are only sent to server(s) with matching names.",
"Access level: $b${level/refreshg}$b",
#include "nickserv.h"
#include "chanserv.h"
+#include "helpfile.h"
#include "hosthiding.h"
#include "proto-common.c"
#include "opserv.h"
*/
#define PREHISTORY 780000000
+#define MODELEN 40 + KEYLEN
+
static struct server *servers_num[64*64];
static privmsg_func_t *privmsg_funcs;
static unsigned int num_privmsg_funcs;
static struct userNode *AddUser(struct server* uplink, const char *nick, const char *ident, const char *hostname, const char *modes, const char *numeric, const char *userinfo, time_t timestamp, const char *realip);
extern int off_channel;
+extern int DefConLevel;
+extern int DefConGlineExpire;
+extern int DefConTimeOut;
+extern char *DefConChanModes;
+extern char *DefConGlineReason;
static int parse_oplevel(char *str);
irc_eob_ack(void)
{
putsock("%s " P10_EOB_ACK, self->numeric);
+
+ char *nick;
+ const char *str;
+ str = conf_get_data("services/opserv/nick", RECDB_QSTRING);
+ nick = strdup(str);
+
+ if (nick && (DefConLevel < 5)) {
+ DefConProcess(GetUserH(nick));
+
+ if (DefConTimeOut > 0)
+ timeq_add(now + DefConTimeOut, defcon_timeout, NULL);
+ }
}
void
NickChange(user, argv[1], 1);
} else {
struct server *serv;
+ struct userNode *nuser;
char modes[MAXLEN];
/* new nick */
if (argc < 9)
unsplit_string(argv+6, argc-9, modes);
else
strcpy(modes, "+");
- AddUser(serv, argv[1], argv[4], argv[5], modes, argv[argc-2], argv[argc-1], atoi(argv[3]), argv[argc-3]);
+ nuser = AddUser(serv, argv[1], argv[4], argv[5], modes, argv[argc-2], argv[argc-1], atoi(argv[3]), argv[argc-3]);
+ if (checkDefCon(DEFCON_GLINE_NEW_CLIENTS) && !IsOper(nuser)) {
+ char target[IRC_NTOP_MAX_SIZE + 3] = { '*', '@', '\0' };
+ const char *str;
+
+ str = conf_get_data("services/opserv/nick", RECDB_QSTRING);
+ if (str) {
+ strcpy(target + 2, nuser->hostname);
+ gline_add(str, target, DefConGlineExpire, DefConGlineReason, now, 1, 0);
+ }
+ return 0;
+ }
}
return 1;
}
cn->timestamp = atoi(argv[argc-1]);
}
+ if (checkDefCon(DEFCON_NO_MODE_CHANGE) && !IsOper(un)) {
+ const char *str;
+ str = conf_get_data("services/opserv/nick", RECDB_QSTRING);
+ if (str) {
+ char modes[MODELEN];
+ struct userNode *opserv = GetUserH(str);
+
+ send_message_type(4, un, opserv, "Channel modes cannot be changed due to DefCon level %d in effect, please try again soon", DefConLevel);
+ irc_make_chanmode(cn, modes);
+ irc_mode(opserv, cn, modes);
+ irc_mode(opserv, cn, DefConChanModes);
+ }
+ return 1;
+ }
+
+
return mod_chanmode(un, cn, argv+2, argc-2, MCP_ALLOW_OVB|MCP_FROM_SERVER|(un ? MC_NOTIFY : 0));
}
pd.user = GetUserH(origin);
if (!pd.user || (IsGagged(pd.user) && !IsOper(pd.user)))
return 1;
+
+ if (checkDefCon(DEFCON_OPER_ONLY) && !IsOper(pd.user)) {
+ const char *str;
+ str = conf_get_data("services/opserv/nick", RECDB_QSTRING);
+ if (str)
+ send_message_type(4, pd.user, GetUserH(str), "Services are currently not available, please try again soon");
+ return 1;
+ }
+
+ if (checkDefCon(DEFCON_SILENT_OPER_ONLY) && !IsOper(pd.user))
+ return 1; /* Silently Ignore */
+
pd.is_notice = 0;
pd.text = argv[2];
parse_foreach(argv[1], privmsg_chan_helper, NULL, privmsg_user_helper, privmsg_invalid, &pd);
// how long to keep an illegal channel locked down (seconds)?
"purge_lock_delay" "60";
+ // ------------------------------------------------------------------
+ // Defcon Settings
+ //
+ // No new channel registrations 1
+ // No New Nick Registrations 2
+ // No Channel Mode changes 4
+ // Force Chan Mode 8
+ // Use Reduced Session Limit 16
+ // KILL any new clients trying to connect 32
+ // Services will ignore everyone but opers 64
+ // Services will silently ignore everyone but opers 128
+ // GLINE all new clients trying to connect 256
+ // No new memos sent to block MemoServ attacks 512
+ //
+ // These are the values are added together to determine each defcon setting:
+ "DefCon1" "415";
+ "DefCon2" "159";
+ "DefCon3" "31";
+ "DefCon4" "23";
+
+ // Default defcon level, 5 is running all normally
+ "DefConLevel" "5";
+
+ // If defcon is limiting sessions then how many sessions should O3 allow?
+ "DefConSessionLimit" "2";
+
+ // Length of the gline set on newly connecting clients, if defcon is glining
+ // newly connecting clients
+ "DefConGlineExpire" "5m";
+
+ // Mode to set on all channels if defcon is forcing channel modes on all channels
+ "DefConChanModes" "+r";
+
+ // If not set to 0, defcon will set back to level 5 after this time
+ "DefConTimeOut" "15m";
+
+ // Where will the user global notices go to?
+ // 1 - Users Only
+ // 2 - Channels Only
+ // 3 - Both Users and Channels
+ "DefConGlobalTarget" "3";
+
+ // Set to 1 to send a notice to all users when defcon levels are changed
+ "GlobalOnDefcon" "0";
+
+ // If set to 1 along with the notice that the levels are changing an extra
+ // notice will be sent
+ "GlobalOnDefconMore" "0";
+
+ // GlobalOnDefconMore notice.
+ "DefconMessage" "Put your message to send your users here. Dont forget to uncomment GlobalOnDefconMore";
+
+ // This notice will be used if GlobalOnDefcon and GlobalOnDefconMore are off
+ "DefConOffMessage" "Services are now back to normal, sorry for any inconvenience";
+
+ // Reason placed in defcon Glines.
+ "DefConGlineReason" "This network is currently not accepting connections, please try again later";
+
+ // ------------------------------------------------------------------
+
// The join-flood policer code goes off all the time when a server
// goes down (and everyone reconnects) so i don't reccomend using it.
// Automatically moderate join flooded channels?