Merge branch 'master' into SpamServ
[srvx.git] / src / spamserv.c
index 1930dd05956555b3e72454946e9265685e2e0476..e15008e76d6e48814694351e846279bc184be227 100644 (file)
 #define KEY_INFO                     "info"
 #define KEY_EXCEPTLEVEL              "exceptlevel"
 #define KEY_EXPIRY                   "expiry"
+#define KEY_LASTBADWORDID            "last_badword_id"
+#define KEY_BADWORDS                 "badwords"
+
+#define KEY_BADWORD_MASK             "mask"
+#define KEY_BADWORD_TRIGGERED        "count"
+#define KEY_BADWORD_ACTION           "action"
+#define KEY_BADWORDID                "badwordid"
 
 #define KEY_DEBUG_CHANNEL            "debug_channel"
 #define KEY_OPER_CHANNEL            "oper_channel"
@@ -300,7 +307,8 @@ spamserv_cs_move_merge(struct userNode *user, struct chanNode *channel, struct c
                else
                        snprintf(reason, sizeof(reason), "$X (channel %s) merged into %s by %s.", channel->name, target->name, user->handle_info->handle);
 
-               global_message(MESSAGE_RECIPIENT_OPERS | MESSAGE_RECIPIENT_HELPERS, reason);
+               /*global_message(MESSAGE_RECIPIENT_OPERS | MESSAGE_RECIPIENT_HELPERS, reason);*/
+               spamserv_oper_message("%s", reason);
                return 1;
        }
 
@@ -336,7 +344,7 @@ spamserv_cs_unregister(struct userNode *user, struct chanNode *channel, enum cs_
                        spamserv_part_channel(channel, partmsg);
                
                spamserv_unregister_channel(cInfo);
-               global_message(MESSAGE_RECIPIENT_OPERS | MESSAGE_RECIPIENT_HELPERS, global);
+               spamserv_oper_message(SSMSG_CHANNEL_UNREGISTERED, spamserv->nick, channel->name, user->handle_info->handle);
        }
 }
 
@@ -586,7 +594,11 @@ spamserv_user_join(struct modeNode *mNode)
 
        if(user->uplink->burst || !(cInfo = get_chanInfo(channel->name)) || !CHECK_JOINFLOOD(cInfo) || !(uInfo = get_userInfo(user->nick)))
                return 0;
-        
+
+       if(IsOper(user))
+       {
+               return 0;
+       }
         
     if(!CHECK_CHANOPS(cInfo))
        {
@@ -1091,7 +1103,6 @@ static
 SPAMSERV_FUNC(cmd_register)
 {
        struct chanInfo *cInfo;
-       char reason[MAXLEN];
 
        if(!channel || !channel->channel_info)
        {
@@ -1174,7 +1185,7 @@ SPAMSERV_FUNC(cmd_unregister)
        
        spamserv_unregister_channel(cInfo);     
 
-       spamserv_oper_message(SSMSG_CHANNEL_UNREGISTERED, channel->name, user->handle_info->handle);
+       spamserv_oper_message(SSMSG_CHANNEL_UNREGISTERED, spamserv->nick, channel->name, user->handle_info->handle);
        ss_reply("SSMSG_UNREG_SUCCESS", channel->name);
 
        return 1;
@@ -1886,6 +1897,45 @@ spamserv_punish(struct chanNode *channel, struct userNode *user, time_t expires,
        KickChannelUser(user, channel, spamserv, reason);       
 }
 
+static void
+spamserv_detected_badword(struct userNode *user, struct chanNode *chan, struct badword *badword)
+{
+    char *hostmask;
+    char *reason = SSMSG_BADWORD_DETECTED;
+    char mask[IRC_NTOP_MAX_SIZE+3] = { '*', '@', '\0' };
+    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, spamserv->nick, now, now, now + spamserv_conf.long_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(spamserv, chan, &change);
+            free(hostmask);
+            break;
+        case BADACTION_KICK:
+            if(GetUserMode(chan, user))
+            KickChannelUser(user, chan, spamserv, reason);
+            break;
+        case BADACTION_KILL:
+            DelUser(user, spamserv, 1, reason);
+            break;
+        case BADACTION_GLINE:
+            irc_ntop(mask + 2, sizeof(mask) - 2, &user->ip);
+            gline_add(spamserv->nick, mask, spamserv_conf.gline_duration, reason, now, now, 0, 1);
+            break;
+        default:
+            //error?
+            break;
+    }
+}
+
 void
 spamserv_channel_message(struct chanNode *channel, struct userNode *user, char *text)
 {
@@ -1900,6 +1950,11 @@ spamserv_channel_message(struct chanNode *channel, struct userNode *user, char *
        if(!spamserv || quit_services || !GetUserMode(channel, spamserv) || !(cInfo = get_chanInfo(channel->name)) || !(uInfo = get_userInfo(user->nick)))
                return;
 
+       if(IsOper(user))
+       {
+               return;
+       }
+
        if(!CHECK_CHANOPS(cInfo))
        {
                struct modeNode *mn = GetUserMode(channel, user);
@@ -2395,6 +2450,10 @@ init_spamserv(const char *nick)
        modcmd_register(spamserv_module, "ADDEXCEPTION", cmd_addexception, 1, MODCMD_REQUIRE_AUTHED|MODCMD_REQUIRE_CHANNEL, NULL);
        modcmd_register(spamserv_module, "DELEXCEPTION", cmd_delexception, 1, MODCMD_REQUIRE_AUTHED|MODCMD_REQUIRE_CHANNEL, NULL);
        modcmd_register(spamserv_module, "STATUS", cmd_status, 1, 0, NULL);
+    modcmd_register(spamserv_module, "ADDBAD", cmd_addbad, 2, MODCMD_REQUIRE_AUTHED|MODCMD_REQUIRE_CHANNEL, NULL);
+    modcmd_register(spamserv_module, "DELBAD", cmd_delbad, 2, MODCMD_REQUIRE_AUTHED|MODCMD_REQUIRE_CHANNEL, NULL);
+    modcmd_register(spamserv_module, "SETBAD", cmd_setbad, 2, MODCMD_REQUIRE_AUTHED|MODCMD_REQUIRE_CHANNEL, NULL);
+    modcmd_register(spamserv_module, "LISTBAD", cmd_listbad, 1, MODCMD_REQUIRE_AUTHED|MODCMD_REQUIRE_CHANNEL, NULL);
        modcmd_register(spamserv_module, "SET", cmd_set, 1, MODCMD_REQUIRE_AUTHED|MODCMD_REQUIRE_CHANNEL, NULL);
        modcmd_register(spamserv_module, "SET SPAMLIMIT", opt_spamlimit, 1, MODCMD_REQUIRE_AUTHED|MODCMD_REQUIRE_CHANNEL, NULL);
        modcmd_register(spamserv_module, "SET ADVREACTION", opt_advreaction, 1, MODCMD_REQUIRE_AUTHED|MODCMD_REQUIRE_CHANNEL, NULL);