Hi,
This patch has three separate patches that you might want to commit
in three pieces.
1) I wrote the original ircd-parser.y, I find it offensive that someone
else is claiming ownership of this. The least they should have done
is add a "derived from" notice to the comments. It never made
sense to me to add my copyright name on a GPL piece of code.
2) you need a #include <sys/types.h> for adns to compile on freebsd
frankly, adns is a piece of shit and should be ripped out.
3) the anti join/part spambot code. I've tried to make it fit into
ircu standards, it would need another pass by someone but it works
as is. I tested it. It should patch against .11 as well easily.
It has been extremely effective in stopping join/spam/part bots on
EFnet for many years.
Enjoy
- Dianora.
Index: ircu2.10/adns/src/adns.h
===================================================================
RCS file: /cvsroot/undernet-ircu/ircu2.10/adns/src/adns.h,v
retrieving revision 1.1
diff -u -r1.1 adns.h
--- ircu2.10/adns/src/adns.h 16 Jun 2002 22:59:33 -0000 1.1
+++ ircu2.10/adns/src/adns.h 16 Feb 2004 04:40:07 -0000
@@ -58,6 +58,7 @@
#define ADNS_H_INCLUDED
#include <stdio.h>
+#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
Index: ircu2.10/adns/src/config.h
===================================================================
RCS file: /cvsroot/undernet-ircu/ircu2.10/adns/src/config.h,v
retrieving revision 1.1
diff -u -r1.1 config.h
--- ircu2.10/adns/src/config.h 16 Jun 2002 22:59:33 -0000 1.1
+++ ircu2.10/adns/src/config.h 16 Feb 2004 04:40:07 -0000
@@ -17,7 +17,7 @@
#define HAVE_GNUC25_PRINTFFORMAT 1
/* Define if we want to include rpc/types.h. Crap BSDs put INADDR_LOOPBACK there. */
-/* #undef HAVEUSE_RPCTYPES_H */
+#define HAVEUSE_RPCTYPES_H 1
/* Define if you have the poll function. */
#define HAVE_POLL 1
Index: ircu2.10/include/channel.h
===================================================================
RCS file: /cvsroot/undernet-ircu/ircu2.10/include/channel.h,v
retrieving revision 1.37
diff -u -r1.37 channel.h
--- ircu2.10/include/channel.h 21 Jan 2004 02:56:57 -0000 1.37
+++ ircu2.10/include/channel.h 16 Feb 2004 04:40:07 -0000
@@ -403,4 +403,40 @@
unsigned int flags);
extern int joinbuf_flush(struct JoinBuf *jbuf);
+/* ANTISPAM join/part bot code.
+ *
+ * You might want to make these tweakable with an oper command
+ * Or move them into config.h
+ *
+ * - Dianora
+ */
+/* Minimum length of time on a channel that a client has to be on
+ * before its not considered a possible spam bot.
+ */
+#define MIN_JOIN_LEAVE_TIME 60
+/* So opers don't get overly spammed about spambots, only warn
+ * every OPER_SPAM_COUNTDOWN times. You could remove this code.
+ */
+#define OPER_SPAM_COUNTDOWN 5
+/* After a client leaves, we zero the counters after this length
+ * of time. i.e. if a client is well behaved, we simply zero.
+ */
+#define JOIN_LEAVE_COUNT_EXPIRE_TIME 120
+
+/* These are leftovers from hybrids /quote set, for now I have
+ * left them in. You can remove as you wish.
+ */
+#define MIN_SPAM_NUM 5
+#define MIN_SPAM_TIME 60
+/* This is a leftover from hybrids /quote set system.
+ */
+#define MAX_JOIN_LEAVE_COUNT 25
+
+/* You will really want to tweak these, but these aren't bad if
+ * they have to be statically defined.
+ */
+#define SPAM_TIME MIN_JOIN_LEAVE_TIME
+#define SPAM_NUM MIN_SPAM_NUM
+
+extern void check_spambot_warning(struct Client *source_p, const char *name);
#endif /* INCLUDED_channel_h */
Index: ircu2.10/include/client.h
===================================================================
RCS file: /cvsroot/undernet-ircu/ircu2.10/include/client.h,v
retrieving revision 1.29
diff -u -r1.29 client.h
--- ircu2.10/include/client.h 12 Aug 2003 09:41:16 -0000 1.29
+++ ircu2.10/include/client.h 16 Feb 2004 04:40:08 -0000
@@ -245,6 +245,17 @@
char cli_name[HOSTLEN + 1]; /* Unique name of the client, nick or host */
char cli_username[USERLEN + 1]; /* username here now for auth stuff */
char cli_info[REALLEN + 1]; /* Free form additional client information */
+
+ /* Anti flooding part, all because of lamers... */
+ time_t last_join_time; /* when this client last
+ joined a channel */
+ time_t last_leave_time; /* when this client last
+ * left a channel */
+ int join_leave_count; /* count of JOIN/LEAVE in less than
+ MIN_JOIN_LEAVE_TIME seconds */
+ int oper_warn_count_down; /* warn opers of this possible
+ spambot every time this gets to 0 */
+
};
#define CLIENT_MAGIC 0x4ca08286
@@ -538,6 +549,14 @@
struct Connection** con_p);
extern void client_set_privs(struct Client *client, struct ConfItem *oper);
extern int client_report_privs(struct Client* to, struct Client* client);
+
+/* ANTISPAM bot patch
+ * - Dianora
+ */
+#define cli_last_join_time(cli) ((cli)->last_join_time)
+#define cli_last_leave_time(cli) ((cli)->last_leave_time)
+#define cli_join_leave_count(cli) ((cli)->join_leave_count)
+#define cli_oper_warn_count_down(cli) ((cli)->oper_warn_count_down)
#endif /* INCLUDED_client_h */
Index: ircu2.10/include/ircd_alloc.h
===================================================================
RCS file: /cvsroot/undernet-ircu/ircu2.10/include/ircd_alloc.h,v
retrieving revision 1.5
diff -u -r1.5 ircd_alloc.h
--- ircu2.10/include/ircd_alloc.h 11 Jan 2003 12:49:25 -0000 1.5
+++ ircu2.10/include/ircd_alloc.h 16 Feb 2004 04:40:08 -0000
@@ -34,6 +34,12 @@
#define MyMalloc(size) \
DoMalloc(size, "malloc", __FILE__, __LINE__)
+/* XXX This is needed by the engine_kqeue.c code
+ * not sure where it is supposed to be
+ * -Dianora
+ */
+#define MyRealloc(ptr,size) realloc(ptr,size)
+
#define MyCalloc(nelem, size) \
DoMallocZero(size * nelem, "calloc", __FILE__, __LINE__)
Index: ircu2.10/ircd/channel.c
===================================================================
RCS file: /cvsroot/undernet-ircu/ircu2.10/ircd/channel.c,v
retrieving revision 1.86
diff -u -r1.86 channel.c
--- ircu2.10/ircd/channel.c 21 Jan 2004 02:56:57 -0000 1.86
+++ ircu2.10/ircd/channel.c 16 Feb 2004 04:40:09 -0000
@@ -3143,7 +3143,7 @@
if (IsUserParting(member))
return;
SetUserParting(member);
-
+
/* Send notification to channel */
if (!(flags & CHFL_ZOMBIE))
sendcmdto_channel_butserv_butone(jbuf->jb_source, CMD_PART, chan, NULL,
@@ -3255,4 +3255,67 @@
if (lp->value.chptr == chptr)
return 1;
return 0;
+}
+
+/* check_spambot_warning()
+ *
+ * inputs - Client to check, channel name or NULL if this is a part.
+ * output - NONE
+ * side effects - Updates the client's oper_warn_count_down, warns the
+ * IRC operators if necessary, and updates
+ * join_leave_countdown as needed.
+ */
+void
+check_spambot_warning(struct Client *source_p, const char *name)
+{
+ time_t t_delta;
+ int decrement_count;
+
+ if (source_p->join_leave_count >= SPAM_NUM)
+ {
+ if (source_p->oper_warn_count_down > 0)
+ source_p->oper_warn_count_down--;
+ else
+ source_p->oper_warn_count_down = 0;
+ if (source_p->oper_warn_count_down == 0)
+ {
+ /* Its already known as a possible spambot */
+ if (name != NULL)
+ sendto_opmask_butone(0, SNO_OLDSNO,
+ "User %s ([EMAIL PROTECTED]) trying to join %s is a
possible spambot",
+ cli_name(source_p), cli_username(source_p),
+ cli_sockhost(source_p), name);
+ else
+ sendto_opmask_butone(0, SNO_OLDSNO,
+ "User %s ([EMAIL PROTECTED]) is a possible spambot",
+ cli_name(source_p), cli_username(source_p),
+ cli_sockhost(source_p));
+
+ cli_oper_warn_count_down(source_p) = OPER_SPAM_COUNTDOWN;
+ }
+ }
+ else
+ {
+ if ((t_delta = (CurrentTime - source_p->last_leave_time)) >
+ JOIN_LEAVE_COUNT_EXPIRE_TIME)
+ {
+ decrement_count = (t_delta / JOIN_LEAVE_COUNT_EXPIRE_TIME);
+ if (decrement_count > source_p->join_leave_count)
+ source_p->join_leave_count = 0;
+ else
+ source_p->join_leave_count -= decrement_count;
+ }
+ else
+ {
+ if ((CurrentTime - (source_p->last_join_time)) < SPAM_TIME)
+ {
+ /* oh, its a possible spambot */
+ source_p->join_leave_count++;
+ }
+ }
+ if (name != NULL)
+ cli_last_join_time(source_p) = CurrentTime;
+ else
+ cli_last_leave_time(source_p) = CurrentTime;
+ }
}
Index: ircu2.10/ircd/ircd.c
===================================================================
RCS file: /cvsroot/undernet-ircu/ircu2.10/ircd/ircd.c,v
retrieving revision 1.64
diff -u -r1.64 ircd.c
--- ircu2.10/ircd/ircd.c 11 Jan 2003 05:46:50 -0000 1.64
+++ ircu2.10/ircd/ircd.c 16 Feb 2004 04:40:09 -0000
@@ -571,9 +571,14 @@
/*----------------------------------------------------------------------------
* set_userid_if_needed()
*--------------------------------------------------------------------------*/
-static int set_userid_if_needed(void) {
- if (getuid() == 0 || geteuid() == 0 ||
+static int
+set_userid_if_needed(void)
+{
+ if (getuid() == 0 || geteuid() == 0) {
+#if 0
+ /* grrr I run my user account as group 0 - Dianora */
getgid() == 0 || getegid() == 0) {
+#endif
fprintf(stderr, "ERROR: This server will not run as superuser.\n");
return 0;
}
Index: ircu2.10/ircd/ircd_parser.y
===================================================================
RCS file: /cvsroot/undernet-ircu/ircu2.10/ircd/ircd_parser.y,v
retrieving revision 1.10
diff -u -r1.10 ircd_parser.y
--- ircu2.10/ircd/ircd_parser.y 25 Jan 2004 01:41:21 -0000 1.10
+++ ircu2.10/ircd/ircd_parser.y 16 Feb 2004 04:40:10 -0000
@@ -1,7 +1,7 @@
/*
* ircd_parser.y: A yacc/bison parser for ircd config files.
* This is part of ircu, an Internet Relay Chat server.
- * The contents of this file are Copyright(C) 2001 by Andrew Miller, the
+ * The contents of this file are Copyright(C) 2001 by Diane Bruce, the
* ircd-hybrid team and the ircu team.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -196,9 +196,7 @@
| HOURS { $$ = 60 * 60; }
| DAYS { $$ = 60 * 60 * 24; }
| WEEKS { $$ = 60 * 60 * 24 * 7; }
-| MONTHS { $$ = 60 * 60 * 24 * 7 * 4; }
-| YEARS { $$ = 60 * 60 * 24 * 365; }
-| DECADES { $$ = 60 * 60 * 24 * 365 * 10; };
+| MONTHS { $$ = 60 * 60 * 24 * 7 * 4; } ;
sizespec: expr {
@@ -237,14 +235,6 @@
}
| expr '/' expr {
$$ = $1 / $3;
- }
-/* leave this out until we find why it makes BSD yacc dump core -larne
- | '-' expr %prec NEG
- = {
- $$ = -$2;
- } */
- | '(' expr ')' {
- $$ = $2;
}
;
Index: ircu2.10/ircd/m_join.c
===================================================================
RCS file: /cvsroot/undernet-ircu/ircu2.10/ircd/m_join.c,v
retrieving revision 1.23
diff -u -r1.23 m_join.c
--- ircu2.10/ircd/m_join.c 22 Jun 2003 13:42:40 -0000 1.23
+++ ircu2.10/ircd/m_join.c 16 Feb 2004 04:40:10 -0000
@@ -175,6 +175,7 @@
char *chanlist;
char *name;
char *keys;
+ int successful_join_count = 0; /* Number of channels successfully joined */
if (parc < 2 || *parv[1] == '\0')
return need_more_params(sptr, "JOIN");
@@ -298,9 +299,11 @@
send_reply(sptr, i, chptr->chname);
continue;
}
+
} /* else if ((i = can_join(sptr, chptr, keys))) */
joinbuf_join(&join, chptr, flags);
+ ++successful_join_count;
if (is_level0_op)
{
joinbuf_flush(&join);
@@ -330,6 +333,9 @@
send_reply(sptr, RPL_TOPICWHOTIME, chptr->chname, chptr->topic_nick,
chptr->topic_time);
}
+
+ if (successful_join_count != 0)
+ cli_last_join_time(sptr) = CurrentTime;
do_names(sptr, chptr, NAMES_ALL|NAMES_EON); /* send /names list */
}
Index: ircu2.10/ircd/m_part.c
===================================================================
RCS file: /cvsroot/undernet-ircu/ircu2.10/ircd/m_part.c,v
retrieving revision 1.7
diff -u -r1.7 m_part.c
--- ircu2.10/ircd/m_part.c 7 Jan 2003 10:06:39 -0000 1.7
+++ ircu2.10/ircd/m_part.c 16 Feb 2004 04:40:10 -0000
@@ -146,6 +146,8 @@
parts.jb_comment = 0;
}
+ if (!IsOper(sptr))
+ check_spambot_warning(sptr, NULL);
joinbuf_join(&parts, chptr, flags); /* part client from channel */
}