added BotNet scanner to NeonSpam
[NeonServV5.git] / src / event_neonspam_chanmsg.c
index f55635a0e08b5c8608db34234db265345642a286..7bcd4b5016dcc6526cb31cee7f0d147c88791bed 100644 (file)
@@ -17,6 +17,7 @@
 
 static int neonspam_spamscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message);
 static int neonspam_floodscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser);
+static int neonspam_botnetscan(struct ClientSocket *client, struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message);
 
 static USERAUTH_CALLBACK(neonspam_event_chanmsg_nick_lookup);
 static void neonspam_event_chanmsg_punish(struct ClientSocket *client, struct ChanUser *chanuser, struct NeonSpamSettings *settings, int action, char *reason, char *reaction);
@@ -87,6 +88,15 @@ static void neonspam_event_chanmsg(struct UserNode *user, struct ChanNode *chan,
                 break;
         }
     }
+    if(action != SPAMSERV_CHECK_PUNISH && (settings->flags & SPAMSETTINGS_BOTNETSCAN)) {
+        result = neonspam_botnetscan(client, settings, chanuser, message);
+        switch(result) {
+            case SPAMSERV_CHECK_DEAD:
+                return;
+            case SPAMSERV_CHECK_IGNORE:
+                break;
+        }
+    }
     //some other checks?
     
     if(action != SPAMSERV_CHECK_IGNORE) {
@@ -126,21 +136,26 @@ static void neonspam_event_chanmsg_punish(struct ClientSocket *client, struct Ch
     if(action == SPAMSERV_CHECK_WARN) {
         reply(client, chanuser->user, "%s", reason);
     } else if(action == SPAMSERV_CHECK_PUNISH) {
-        MYSQL_RES *res;
-        MYSQL_ROW row;
         loadChannelSettings(chanuser->chan);
-        printf_mysql_query("SELECT `%s` FROM `channels` WHERE `channel_id` = '%d'", reaction, chanuser->chan->channel_id);
-        res = mysql_use();
-        row = mysql_fetch_row(res);
-        if(!row[0]) {
-            printf_mysql_query("SELECT `%s` FROM `channels` WHERE `channel_name` = 'defaults'", reaction);
+        int reactionid;
+        if(!(reactionid = atoi(reaction))) {
+            MYSQL_RES *res;
+            MYSQL_ROW row;
+            printf_mysql_query("SELECT `%s` FROM `channels` WHERE `channel_id` = '%d'", reaction, chanuser->chan->channel_id);
             res = mysql_use();
             row = mysql_fetch_row(res);
+            if(!row[0]) {
+                printf_mysql_query("SELECT `%s` FROM `channels` WHERE `channel_name` = 'defaults'", reaction);
+                res = mysql_use();
+                row = mysql_fetch_row(res);
+            }
+            reactionid = atoi(row[0]);
         }
+            
         int duration = 0;
         char banmaskBuf[NICKLEN+USERLEN+HOSTLEN+3];
         char *banmask = NULL;
-        switch (atoi(row[0])) {
+        switch (reactionid) {
             case 2: //TIMEBAN: 3min
                 duration = 180;
             case 3: //TIMEBAN: 1h
@@ -212,4 +227,41 @@ static int neonspam_floodscan(struct NeonSpamSettings *settings, struct ChanUser
         return SPAMSERV_CHECK_IGNORE;
 }
 
-
+static int neonspam_botnetscan(struct ClientSocket *client, struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message) {
+    //crc32 hash of the message
+    unsigned long msghash = crc32(message);
+    if((time(0) - settings->lastmsg_time) > BOTNETSCAN_TIME || settings->lastmsg != msghash) {
+        int i;
+        for(i = 0; i < BOTNETSCAN_USERS; i++) {
+            if(settings->botnicks[i]) {
+                free(settings->botnicks[i]);
+                settings->botnicks[i] = NULL;
+            }
+        }
+        settings->flags &= ~SPAMSETTINGS_KICKEDBOTQUEUE;
+        settings->lastmsg = msghash;
+    } else if(settings->lastmsg == msghash) {
+        int i;
+        for(i = 0; i < BOTNETSCAN_USERS; i++) {
+            if(!settings->botnicks[i]) {
+                settings->botnicks[i] = strdup(chanuser->user->nick);
+                break;
+            } else if(!stricmp(chanuser->user->nick, settings->botnicks[i])) {
+                return SPAMSERV_CHECK_IGNORE;
+            }
+        }
+        if(i == BOTNETSCAN_USERS) {
+            //BOTNETSCAN_USERS exceeded
+            if(!(settings->flags & SPAMSETTINGS_KICKEDBOTQUEUE)) {
+                for(i = 0; i < BOTNETSCAN_USERS; i++) {
+                    putsock(client, "KICK %s %s :%s", chanuser->chan->name, settings->botnicks[i], SPAMSERV_MSG_BOTNET);
+                }
+                settings->flags |= SPAMSETTINGS_KICKEDBOTQUEUE;
+            }
+            putsock(client, "KICK %s %s :%s", chanuser->chan->name, chanuser->user->nick, SPAMSERV_MSG_BOTNET);
+            return SPAMSERV_CHECK_DEAD;
+        }
+    }
+    settings->lastmsg_time = time(0);
+    return SPAMSERV_CHECK_IGNORE;
+}