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);
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) {
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
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;
+}