X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=src%2Fmod-watchdog.c;h=c70ab70233be1094e17cadbd6224e93cbe5e13d9;hb=ba891f830590ca957720345fd9dd66dfccc54c1f;hp=99527db0e8b5623e416aa116b915fbde79d028e6;hpb=7989887034536e5c22130653a8b7ac31cd0d34bc;p=srvx.git diff --git a/src/mod-watchdog.c b/src/mod-watchdog.c index 99527db..c70ab70 100644 --- a/src/mod-watchdog.c +++ b/src/mod-watchdog.c @@ -23,6 +23,9 @@ * "watchdog" { * "nick" "Watchdog"; * "modes" "+iok"; + "ban_duration" "2h"; //only if the channel is registered with chanserv + "gline_duration" "1h"; + "punishment_reason" "Your message contained a forbidden word."; * }; * }; * @@ -34,6 +37,7 @@ #include "modcmd.h" #include "saxdb.h" #include "timeq.h" +#include "gline.h" #define KEY_BADWORDS "badwords" #define KEY_BADWORD_MASK "mask" @@ -79,6 +83,9 @@ struct watchdog_channel { static struct { const char *nick; const char *modes; + const char *punishment_reason; + unsigned long ban_duration; + unsigned long gline_duration; } watchdog_conf; const char *watchdog_module_deps[] = { NULL }; @@ -278,20 +285,42 @@ static MODCMD_FUNC(cmd_listbad) static MODCMD_FUNC(cmd_register) { dict_iterator_t it; + struct modeNode *mn; - if((argc < 2) || !IsChannelName(argv[1])) + if(channel) { - reply("MSG_NOT_CHANNEL_NAME"); - return 0; - } - if(opserv_bad_channel(argv[1])) - { - reply("CSMSG_ILLEGAL_CHANNEL", argv[1]); - return 0; + if(channel->bad_channel) + { + reply("CSMSG_ILLEGAL_CHANNEL", channel->name); + return 0; + } + + if(!IsHelping(user) + && (!(mn = GetUserMode(channel, user)) || !(mn->modes & MODE_CHANOP))) + { + reply("CSMSG_MUST_BE_OPPED", channel->name); + return 0; + } + } + else + { - channel = AddChannel(argv[1], now, NULL, NULL); + if((argc < 2) || !IsChannelName(argv[1])) + { + reply("MSG_NOT_CHANNEL_NAME"); + return 0; + } + + if(opserv_bad_channel(argv[1])) + { + reply("CSMSG_ILLEGAL_CHANNEL", argv[1]); + return 0; + } + + channel = AddChannel(argv[1], now, NULL, NULL); + } for (it = dict_first(chanlist); it; it = iter_next(it)) { struct watchdog_channel *chan = iter_data(it); @@ -319,7 +348,9 @@ static MODCMD_FUNC(cmd_unregister) if(chan && chan->channel == channel) { //found, unregister it! - DelChannelUser(watchdog, channel, "unregistered.", 0); + char reason[MAXLEN]; + sprintf(reason, "Unregistered by %s.", user->handle_info->handle); + DelChannelUser(watchdog, channel, reason, 0); dict_remove(chanlist, channel->name); reply("CSMSG_UNREG_SUCCESS", channel->name); return 1; @@ -331,9 +362,60 @@ static MODCMD_FUNC(cmd_unregister) } static void -watchdog_channel_message(struct userNode *user, struct chanNode *chan, const char *text, struct userNode *bot, unsigned int is_notice) +watchdog_detected_badword(struct userNode *user, struct chanNode *chan, struct badword *badword) +{ + char *hostmask; + char *reason = watchdog_conf.punishment_reason; + char mask[IRC_NTOP_MAX_SIZE+3] = { '*', '@', '\0' }; + if(!IsOper(user)) { + switch(badword->action) { + case BADACTION_BAN: + hostmask = generate_hostmask(user, GENMASK_STRICT_HOST | GENMASK_ANY_IDENT); + sanitize_ircmask(hostmask); + if(chan->channel_info) { + //registered channel + add_channel_ban(chan->channel_info, hostmask, watchdog->nick, now, now, now + watchdog_conf.ban_duration, reason); + } + struct mod_chanmode change; + mod_chanmode_init(&change); + change.argc = 1; + change.args[0].mode = MODE_BAN; + change.args[0].u.hostmask = hostmask; + mod_chanmode_announce(watchdog, chan, &change); + free(hostmask); + + case BADACTION_KICK: + if(GetUserMode(chan, user)) + KickChannelUser(user, chan, watchdog, reason); + break; + case BADACTION_KILL: + DelUser(user, watchdog, 1, reason); + break; + case BADACTION_GLINE: + irc_ntop(mask + 2, sizeof(mask) - 2, &user->ip); + gline_add(watchdog->nick, mask, watchdog_conf.gline_duration, reason, now, now, 0, 1); + break; + default: + //error? + break; + } + } +} + +static void +watchdog_channel_message(struct userNode *user, struct chanNode *chan, const char *text, UNUSED_ARG(struct userNode *bot), UNUSED_ARG(unsigned int is_notice)) { - //to be continued... + dict_iterator_t it; + + if(!watchdog || !dict_find(chanlist, chan->name, NULL)) + return; + + for (it = dict_first(shitlist); it; it = iter_next(it)) { + struct badword *badword = iter_data(it); + if(match_ircglob(text, badword->badword_mask)) { + watchdog_detected_badword(user, chan, badword); + } + } } static struct badword* @@ -418,6 +500,16 @@ watchdog_conf_read(void) str = database_get_data(conf_node, "modes", RECDB_QSTRING); watchdog_conf.modes = (str ? str : NULL); + + str = database_get_data(conf_node, "ban_duration", RECDB_QSTRING); + watchdog_conf.ban_duration = str ? ParseInterval(str) : ParseInterval("2h"); + + str = database_get_data(conf_node, "gline_duration", RECDB_QSTRING); + watchdog_conf.gline_duration = str ? ParseInterval(str) : ParseInterval("1h"); + + str = database_get_data(conf_node, "punishment_reason", RECDB_QSTRING); + watchdog_conf.punishment_reason = (str ? str : "Your message contained a forbidden word."); + } static int @@ -445,7 +537,7 @@ watchdog_saxdb_read_chanlist(const char *name, void *data, UNUSED_ARG(void *extr struct record_data *rd = data; if (rd->type == RECDB_OBJECT) { - dict_t obj = GET_RECORD_OBJECT(rd); + //dict_t obj = GET_RECORD_OBJECT(rd); /* nothing in here, yet */ add_channel(name); @@ -473,7 +565,6 @@ watchdog_saxdb_read(struct dict *db) static int watchdog_saxdb_write(struct saxdb_context *ctx) { - char str[10]; dict_iterator_t it; saxdb_write_int(ctx, KEY_BADWORDID, last_badword_id); @@ -482,13 +573,15 @@ watchdog_saxdb_write(struct saxdb_context *ctx) saxdb_start_record(ctx, KEY_BADWORDS, 1); for (it = dict_first(shitlist); it; it = iter_next(it)) { struct badword *badword = iter_data(it); - saxdb_start_record(ctx, iter_key(it), 0); - - saxdb_write_string(ctx, KEY_BADWORD_MASK, badword->badword_mask); - saxdb_write_int(ctx, KEY_BADWORD_TRIGGERED, badword->triggered); - saxdb_write_int(ctx, KEY_BADWORD_ACTION, badword->action); - - saxdb_end_record(ctx); + if(badword && badword->badword_mask) { + saxdb_start_record(ctx, iter_key(it), 0); + + saxdb_write_string(ctx, KEY_BADWORD_MASK, badword->badword_mask); + saxdb_write_int(ctx, KEY_BADWORD_TRIGGERED, badword->triggered); + saxdb_write_int(ctx, KEY_BADWORD_ACTION, badword->action); + + saxdb_end_record(ctx); + } } saxdb_end_record(ctx); } @@ -497,9 +590,11 @@ watchdog_saxdb_write(struct saxdb_context *ctx) saxdb_start_record(ctx, KEY_CHANNELS, 1); for (it = dict_first(chanlist); it; it = iter_next(it)) { struct watchdog_channel *wc = iter_data(it); - saxdb_start_record(ctx, wc->channel->name, 0); - //anything else? - saxdb_end_record(ctx); + if(wc && wc->channel && wc->channel->name) { + saxdb_start_record(ctx, wc->channel->name, 0); + //anything else? + saxdb_end_record(ctx); + } } saxdb_end_record(ctx); } @@ -546,7 +641,7 @@ watchdog_init(void) modcmd_register(watchdog_module, "delbad", cmd_delbad, 2, MODCMD_REQUIRE_AUTHED, "flags", "+oper", NULL); modcmd_register(watchdog_module, "setbad", cmd_setbad, 2, MODCMD_REQUIRE_AUTHED, "flags", "+oper", NULL); modcmd_register(watchdog_module, "listbad", cmd_listbad, 1, MODCMD_REQUIRE_AUTHED, "flags", "+oper", NULL); - modcmd_register(watchdog_module, "register", cmd_register, 2, MODCMD_REQUIRE_AUTHED, "flags", "+helping", NULL); + modcmd_register(watchdog_module, "register", cmd_register, 1, MODCMD_REQUIRE_AUTHED, "flags", "+acceptchan,+helping", NULL); modcmd_register(watchdog_module, "unregister", cmd_unregister, 1, MODCMD_REQUIRE_AUTHED | MODCMD_REQUIRE_CHANNEL, "flags", "+helping", NULL); message_register_table(msgtab); @@ -569,5 +664,15 @@ watchdog_finalize(void) { str = database_get_data(conf_node, "modes", RECDB_QSTRING); if (str) watchdog_conf.modes = str; + + str = database_get_data(conf_node, "ban_duration", RECDB_QSTRING); + if (str) watchdog_conf.ban_duration = ParseInterval(str); + + str = database_get_data(conf_node, "gline_duration", RECDB_QSTRING); + if (str) watchdog_conf.gline_duration = ParseInterval(str); + + str = database_get_data(conf_node, "punishment_reason", RECDB_QSTRING); + if (str) watchdog_conf.punishment_reason = str; + return 1; }