Просмотр исходного кода

* Port [3347] to 1.2.14
* Move dronflood code around
* Auto set a random key on lockdown too



svn: 3348

Bryan Drewery 19 лет назад
Родитель
Сommit
83358c6fae
3 измененных файлов с 79 добавлено и 68 удалено
  1. 18 62
      src/mod/irc.mod/chan.c
  2. 58 5
      src/mod/irc.mod/irc.c
  3. 3 1
      src/mod/irc.mod/irc.h

+ 18 - 62
src/mod/irc.mod/chan.c

@@ -2292,24 +2292,6 @@ static int got332(char *from, char *msg)
   return 0;
 }
 
-static time_t flood_im_time = 120;
-rate_t flood_massjoin = { 6, 1 };
-
-void unset_im(struct chanset_t *chan)
-{
-  if (chan->channel.drone_set_mode) {
-    char buf[3] = "", *p = buf;
-    if (chan->channel.drone_set_mode & CHANINV)
-      *p++ = 'i';
-    if (chan->channel.drone_set_mode & CHANMODER)
-      *p++ = 'm';
-    buf[2] = '\0';
-    dprintf(DP_MODE, "MODE %s :-%s\n", chan->name[0] ? chan->name : chan->dname, buf);
-  }
-  chan->channel.drone_set_mode = 0;
-}
-
-
 /* Got a join
  */
 static int gotjoin(char *from, char *chname)
@@ -2438,45 +2420,6 @@ static int gotjoin(char *from, char *chname)
 	m->flags |= STOPWHO;
         irc_log(chan, "%s returned from netsplit", m->nick);
       } else {
-         if (channel_nomassjoin(chan) && me_op(chan)) {
-           if (chan->channel.drone_jointime < now - flood_massjoin.time) {      //expired, reset counter
-             chan->channel.drone_joins = 0;
-           }
-
-           ++chan->channel.drone_joins;
-           chan->channel.drone_jointime = now;
-
-           if (!chan->channel.drone_set_mode && chan->channel.drone_joins >= flood_massjoin.count) {  //flood from dronenet, let's attempt to set +im
-             egg_timeval_t howlong;
-
-             chan->channel.drone_set_mode = 0;
-
-             char buf[3] = "", *p = buf;
-
-             if (!(chan->channel.mode & CHANINV)) {
-               chan->channel.drone_set_mode |= CHANINV;
-               *p++ = 'i';
-             }
-             if (!(chan->channel.mode & CHANMODER)) {
-               chan->channel.drone_set_mode |= CHANMODER;
-               *p++ = 'm';
-             }
-             buf[2] = '\0';
-
-             if (chan->channel.drone_set_mode && buf[0]) {
-               chan->channel.drone_joins = 0;
-               chan->channel.drone_jointime = 0;
-              
-               dprintf(DP_DUMP, "MODE %s :+%s\n", chan->name[0] ? chan->name : chan->dname, buf);
-               howlong.sec = flood_im_time;
-               howlong.usec = 0;
-               timer_create_complex(&howlong, "Unset umode +im", (Function) unset_im, (void *) chan, 0);
-
-               putlog(LOG_MISC, "*", "Drone flood detected in %s! Setting +im for %li seconds.", chan->dname, flood_im_time);
-             }
-           }
-         }
-
 	if (m)
 	  killmember(chan, nick);
 	m = newmember(chan, nick);
@@ -2490,6 +2433,19 @@ static int gotjoin(char *from, char *chname)
 	m->user = u;
         m->tried_getuser = 1;
 
+        if (channel_nomassjoin(chan) && me_op(chan)) {
+          if (chan->channel.drone_jointime < now - flood_massjoin.time) {      //expired, reset counter
+            chan->channel.drone_joins = 0;
+          }
+          ++chan->channel.drone_joins;
+          chan->channel.drone_jointime = now;
+
+          if (!chan->channel.drone_set_mode && chan->channel.drone_joins >= flood_massjoin.count) {  //flood from dronenet, let's attempt to set +im
+            detected_drone_flood(chan, m);
+          }
+        }
+
+
         if (!m->user && doresolv(chan)) {
           if (is_dotted_ip(host)) 
             strlcpy(m->userip, uhost, sizeof(m->userip));
@@ -2977,11 +2933,10 @@ static int gotmsg(char *from, char *msg)
   strcpy(uhost, from);
   nick = splitnick(&uhost);
 
+  memberlist *m = ismember(chan, nick);
+
   /* Only check if flood-ctcp is active */
-  detect_autokick(nick, uhost, chan, msg);
   if (flood_ctcp.count && detect_avalanche(msg)) {
-    memberlist *m = ismember(chan, nick);
-
     u = get_user_by_host(from);
     get_user_flagrec(u, &fr, chan->dname);
     /* Discard -- kick user if it was to the channel */
@@ -3082,11 +3037,12 @@ static int gotmsg(char *from, char *msg)
     int botmatch = 0;
     char *my_msg = NULL, *my_ptr = NULL, *fword = NULL;
 
+    if (me_op(chan) && doflood(chan))
+      detect_offense(m, chan, msg);
+
     /* Check even if we're ignoring the host. (modified by Eule 17.7.99) */
     detect_chan_flood(nick, uhost, from, chan, FLOOD_PRIVMSG, NULL);
     
-    if (!(chan = findchan(realto)))
-      return 0;
     if (auth_chan) {
       my_msg = my_ptr = strdup(msg);
       fword = newsplit(&my_msg);		/* take out first word */

+ 58 - 5
src/mod/irc.mod/irc.c

@@ -69,6 +69,8 @@ static bool prevent_mixing = 1;  /* To prevent mixing old/new modes */
 static bool include_lk = 1;      /* For correct calculation
                                  * in real_add_mode. */
 
+rate_t flood_massjoin = { 6, 1 };
+
 #include "chan.c"
 #include "mode.c"
 #include "cmdsirc.c"
@@ -87,14 +89,12 @@ voice_ok(memberlist *m, struct chanset_t *chan)
 }
 
 static void
-detect_autokick(char *nick, char *uhost, struct chanset_t *chan, char *msg)
+detect_offense(memberlist* m, struct chanset_t *chan, char *msg)
 {
-  if (!nick || !nick[0] || !uhost || !uhost[0] || !chan || !msg || !msg[0])
-    return;
-
   struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0 };
-  struct userrec *u = get_user_by_host(uhost);
+  struct userrec *u = m->user ? m->user : get_user_by_host(m->userhost);
   int i = 0;
+
   //size_t tot = strlen(msg);
 
   get_user_flagrec(u, &fr, chan->dname);
@@ -118,9 +118,62 @@ dprintf(DP_MODE, "PRIVMSG %s :flood stats for %s: %d/%d are CAP, percentage: %d\
 dprintf(DP_HELP, "PRIVMSG %s :cap flood.\n", chan->dname);
   }
 */
+}
+
+void unlock_chan(struct chanset_t *chan)
+{
+  if (chan->channel.drone_set_mode) {
+    char buf[4] = "", *p = buf;
+    if (chan->channel.drone_set_mode & CHANINV)
+      *p++ = 'i';
+    if (chan->channel.drone_set_mode & CHANMODER)
+      *p++ = 'm';
+    if (chan->channel.drone_set_mode & CHANKEY)
+      *p++ = 'k';
+
+    buf[sizeof(buf) - 1] = '\0';
+    dprintf(DP_MODE, "MODE %s :-%s\n", chan->name[0] ? chan->name : chan->dname, buf);
+  }
+  chan->channel.drone_set_mode = 0;
+}
+
+void detected_drone_flood(struct chanset_t* chan, memberlist* m) {
+  egg_timeval_t howlong;
 
+  chan->channel.drone_set_mode = 0;
+
+  char buf[4] = "", *p = buf;
+  char key[10] = "";
+
+  if (!(chan->channel.mode & CHANINV)) {
+    chan->channel.drone_set_mode |= CHANINV;
+    *p++ = 'i';
+  }
+  if (!(chan->channel.mode & CHANMODER)) {
+    chan->channel.drone_set_mode |= CHANMODER;
+    *p++ = 'm';
+  }
+  if (!(chan->channel.mode & CHANKEY)) {
+    chan->channel.drone_set_mode |= CHANKEY;
+    *p++ = 'k';
+    make_rand_str(key, sizeof(key) - 1);
+  }
+  buf[sizeof(buf) - 1] = '\0';
+
+  if (chan->channel.drone_set_mode && buf[0]) {
+    chan->channel.drone_joins = 0;
+    chan->channel.drone_jointime = 0;
+
+    dprintf(DP_DUMP, "MODE %s :+%s %s\n", chan->name[0] ? chan->name : chan->dname, buf, key[0] ? key : "");
+    howlong.sec = chan->flood_lock_time;
+    howlong.usec = 0;
+    timer_create_complex(&howlong, "unlock", (Function) unlock_chan, (void *) chan, 0);
+
+    putlog(LOG_MISC, "*", "Flood detected in %s! Locking for %li seconds.", chan->dname, chan->flood_lock_time);
+  }
 }
 
+
 void notice_invite(struct chanset_t *chan, char *handle, char *nick, char *uhost, bool op) {
   char fhandle[21] = "";
   const char *ops = " (auto-op)";

+ 3 - 1
src/mod/irc.mod/irc.h

@@ -73,7 +73,7 @@ static void flush_mode(struct chanset_t *, int);
 #define resetexempts(chan)  resetmasks((chan), (chan)->channel.exempt, (chan)->exempts, global_exempts, 'e')
 #define resetinvites(chan)  resetmasks((chan), (chan)->channel.invite, (chan)->invites, global_invites, 'I')
 
-static void detect_autokick(char *, char *, struct chanset_t *, char *);
+static void detect_offense(memberlist*, struct chanset_t *, char *);
 /* static int target_priority(struct chanset_t *, memberlist *, int); */
 static bool do_op(char *, struct chanset_t *, time_t, bool);
 static void request_op(struct chanset_t *);
@@ -88,6 +88,8 @@ static char *quickban(struct chanset_t *, char *);
 static bool killmember(struct chanset_t *chan, char *nick);
 static void check_lonely_channel(struct chanset_t *chan);
 static int gotmode(char *, char *);
+void unset_im(struct chanset_t* chan);
+void detected_drone_flood(struct chanset_t* chan, memberlist*);
 #define newban(chan, mask, who)         new_mask((chan)->channel.ban, mask, who)
 #define newexempt(chan, mask, who)      new_mask((chan)->channel.exempt, mask, who)
 #define newinvite(chan, mask, who)      new_mask((chan)->channel.invite, mask, who)