quakenet / newserv

QuakeNet's modular services
https://development.quakenet.org/
Other
24 stars 17 forks source link

Enforce ban on nick change #23

Open retropc opened 8 years ago

retropc commented 8 years ago

When a ban is set on chanserv's banlist and a user joins the channel - he is kicked and banned. However, when a user changes his nick to fit the banmask - he isn't getting kicked and banned.

Example:

[03/10/13 09:02:04] * blal (flaefl@this.is.censored) has joined #thechannel [03/10/13 09:02:40] * Q sets mode: +b [S]!@ [03/10/13 09:02:49] * blal is now known as [S]test [03/10/13 09:03:59] * AnOppedUser sets mode: -b [S]!@ [03/10/13 09:03:59] * Q sets mode: +b [S]!@ [03/10/13 09:03:59] * [S]test was kicked by Q (Banned.) [03/10/13 09:04:17] * AnOppedUser sets mode: -b [S]!@ [03/10/13 09:04:23] * [S]test (flaefl@this.is.censored) has joined #thechannel [03/10/13 09:04:23] * Q sets mode: +b [S]!@ [03/10/13 09:04:23] * [S]test was kicked by Q (Banned.) [03/10/13 09:02:04] * blal (flaefl@this.is.censored) has joined #thechannel [03/10/13 09:02:40] * Q sets mode: +b [S]!@ [03/10/13 09:02:49] * blal is now known as [S]test [03/10/13 09:03:59] * AnOppedUser sets mode: -b [S]!@ [03/10/13 09:03:59] * Q sets mode: +b [S]!@ [03/10/13 09:03:59] * [S]test was kicked by Q (Banned.) [03/10/13 09:04:17] * AnOppedUser sets mode: -b [S]!@ [03/10/13 09:04:23] * [S]test (flaefl@this.is.censored) has joined #thechannel [03/10/13 09:04:23] * Q sets mode: +b [S]!@ [03/10/13 09:04:23] * [S]test was kicked by Q (Banned.)

(originally reported by NaNg)

retropc commented 8 years ago

Patch submitted modul8:

diff -r 3f154eb428a9 chanserv/chanserv.c
--- a/chanserv/chanserv.c   Tue Sep 24 00:35:42 2013 +0100
+++ b/chanserv/chanserv.c   Fri Oct 18 12:42:43 2013 +0200
@@ -105,6 +105,7 @@
   /* Register core hooks */
   registerhook(HOOK_NICK_NEWNICK, cs_handlenick);
   registerhook(HOOK_NICK_ACCOUNT, cs_handlenick);
+  registerhook(HOOK_NICK_RENAME, cs_handlerename);
   registerhook(HOOK_NICK_LOSTNICK, cs_handlelostnick);
   registerhook(HOOK_NICK_SETHOST, cs_handlesethost);
   registerhook(HOOK_CHANNEL_NEWCHANNEL, cs_handlenewchannel);
diff -r 3f154eb428a9 chanserv/chanserv.h
--- a/chanserv/chanserv.h   Tue Sep 24 00:35:42 2013 +0100
+++ b/chanserv/chanserv.h   Fri Oct 18 12:42:43 2013 +0200
@@ -862,6 +862,7 @@
 void cs_docheckchanmodes(channel *cp, modechanges *changes);
 void cs_docheckopvoice(channel *cp, modechanges *changes);
 void cs_checkbans(channel *cp);
+void cs_checknickforban(nick *np);
 void cs_schedupdate(chanindex *cip, int mintime, int maxtime);
 void cs_timerfunc(void *arg);
 void cs_removechannel(regchan *rcp, char *reason);
@@ -894,6 +895,7 @@

 /* chanservnetevents.c */
 void cs_handlenick(int hooknum, void *arg);
+void cs_handlerename(int hooknum, void *arg);
 void cs_handlesethost(int hooknum, void *arg);
 void cs_handlelostnick(int hooknum, void *arg);
 void cs_handlenewchannel(int hooknum, void *arg);
diff -r 3f154eb428a9 chanserv/chanservnetevents.c
--- a/chanserv/chanservnetevents.c  Tue Sep 24 00:35:42 2013 +0100
+++ b/chanserv/chanservnetevents.c  Fri Oct 18 12:42:43 2013 +0200
@@ -20,8 +20,13 @@

 void cs_handlenick(int hooknum, void *arg) {
   nick *np=(nick *)arg;
+  cs_checknick(np);
+}

-  cs_checknick(np);
+void cs_handlerename(int hooknum, void *arg) {
+  void **harg = (void **)arg;
+  cs_checknickforban(harg[0]);
 }

 void cs_handlesethost(int hooknum, void *arg) {
diff -r 3f154eb428a9 chanserv/chanservuser.c
--- a/chanserv/chanservuser.c   Tue Sep 24 00:35:42 2013 +0100
+++ b/chanserv/chanservuser.c   Fri Oct 18 12:42:43 2013 +0200
@@ -860,7 +860,45 @@

   free(ca);
 }
-
+
+void cs_checknickforban(nick *np) {
+  channel **ca;
+  regchan *rcp;
+  int i,j;
+  time_t now;
+  modechanges changes;
+  regban *rbp;
+
+  now = time(NULL);
+
+  if (IsService(np) || IsOper(np) || IsXOper(np))
+    return;
+
+  i=np->channels->cursi;
+  ca=(channel **)malloc(i*sizeof(channel *));
+  memcpy(ca, np->channels->content,i*sizeof(channel *));
+
+  for (j=0;j<i;j++) {
+    localsetmodeinit(&changes, ca[j], chanservnick);
+
+    if ((rcp=ca[j]->index->exts[chanservext])==NULL || CIsSuspended(rcp))
+      continue;
+
+    for (rbp=rcp->bans;rbp;rbp=rbp->next) {
+      if (((!rbp->expiry) || (rbp->expiry <= now)) &&
+          nickmatchban(np, rbp->cbp, 1)) {
+        if (!nickbanned(np, ca[j], 1)) {
+          localdosetmode_ban(&changes, bantostring(rbp->cbp), MCB_ADD);
+        }
+        localkickuser(chanservnick,ca[j],np,rbp->reason?rbp->reason->content:"Banned.");
+        break;
+      }
+    }
+  }
+  localsetmodeflush(&changes,1);
+  free(ca);
+}
+
 void cs_checkbans(channel *cp) {
   regchan *rcp;
   int i;
retropc commented 8 years ago

original comments:

modul8:

Patch for this attached - performance seems acceptable.

retropc:

patch seems to leak memory? also I'm a bit concerned about the potential complexity, it's maxchans * bans_on_chan -> 20 * 50 odd, which I guess isn't that bad, depending on cost of ban matching

modul8:

Reattached :)

retropc:

looks ok (bar maybe 'i' being used for a max value instead of a loop index) still slightly concerned about the complexity...