]> jfr.im git - irc/quakenet/newserv.git/blobdiff - glines/glines_handler.c
GLINES: fix null pointer deref in trustgline / trustungline
[irc/quakenet/newserv.git] / glines / glines_handler.c
index 3d23ff2563d202194f84946757fb1c4e4213ecf0..52b60b8b740b94f3a09a0e3408f6b26ba011f5b1 100644 (file)
@@ -3,6 +3,14 @@
 #include "../localuser/localuserchannel.h"
 #include "glines.h"
 
+//#define DEBUG
+
+#ifdef DEBUG
+#define Debug(...) Error("debuggline", ERR_DEBUG, ##__VA_ARGS__)
+#else
+#define Debug(...)
+#endif
+
 /*
   <prefix> GL <target> [!][+|-|>|<]<mask> [<expiration>] [<lastmod>] [<lifetime>] [:<reason>]
 */
@@ -60,7 +68,7 @@ int handleglinemsg(void *source, int cargc, char **cargv) {
           Error("gline", ERR_WARNING, "Received gline from non-existant server");
           return CMD_ERROR; 
         } else {
-          creator = serverlist[(int)creatornum].name->content, HOSTLEN;
+          creator = serverlist[(int)creatornum].name->content;
         }
       break;
     case 5:
@@ -80,6 +88,11 @@ int handleglinemsg(void *source, int cargc, char **cargv) {
   /* 2nd param is mask */
   mask = cargv[1];
 
+  if (*mask == '%') {
+    flags |= GLINE_DESTROY;
+    mask++;
+  }
+
   switch (*mask) {
     case '+':
       flags |= GLINE_ACTIVATE;
@@ -104,8 +117,8 @@ int handleglinemsg(void *source, int cargc, char **cargv) {
     switch (cargc) {
       case 4:
         /* asuka U:d, no lastmod */
-        lastmod = getnettime();
-        lifetime = gline_max(lastmod, expire);
+        lastmod = 0;
+        lifetime = expire;
         reason = cargv[3];
         break;
       case 5:
@@ -125,34 +138,34 @@ int handleglinemsg(void *source, int cargc, char **cargv) {
          return CMD_ERROR;
     }
 
-    Error("debuggline", ERR_WARNING, "GL Received: Creator %s, Mask %s, Reason %s, Expire %lu, Lastmod %lu, Lifetime %lu", creator, mask, reason, expire, lastmod, lifetime);   
+    Debug("GL Received: Creator %s, Mask %s, Reason %s, Expire %lu, Lastmod %lu, Lifetime %lu", creator, mask, reason, expire, lastmod, lifetime);   
 
     agline = findgline(mask);
 
     if (agline) {
-      if (agline->flags & GLINE_ACTIVE) { 
-        Error("debuggline", ERR_WARNING, "Duplicate Gline recieved for %s - old lastmod %lu, expire %lu, lifetime %lu, reason %s, creator %s", mask, agline->lastmod, agline->expire, agline->lifetime, agline->reason->content, agline->creator->content);
+      Debug("Update for existing gline received for %s - old lastmod %lu, expire %lu, lifetime %lu, reason %s, creator %s", mask, agline->lastmod, agline->expire, agline->lifetime, agline->reason ? agline->reason->content : "", agline->creator->content);
+
+      agline->flags |= GLINE_ACTIVE;
+
+      /* check lastmod then assume the new gline is authoritive */
+      if (lastmod > agline->lastmod) {
+        agline->lastmod = lastmod;
+        agline->expire = expire;
+        agline->lifetime = lifetime;
+        freesstring(agline->creator);
+        agline->creator = getsstring(creator, 255);
+        freesstring(agline->reason);
+        agline->reason = getsstring(reason, 255); 
       } else {
-        /* we're reactivating a gline - check lastmod then assume the new gline is authoritive */
-        if (lastmod > agline->lastmod) {
-          agline->lastmod = lastmod;
-          agline->expire = expire;
-          agline->lifetime = lifetime;
-          agline->creator = getsstring(creator, 255);
-          freesstring(agline->reason);
-          agline->reason = getsstring(reason, 255); 
-          agline->flags |= GLINE_ACTIVE;
-        } else {
-          Error("debuggline", ERR_WARNING, "received a gline with a lower lastmod");
-          /* @@@TODO resend our gline ? */
-        } 
-      }
-      /* TODO */
-      return CMD_ERROR;
+        Debug("received a gline with a lower lastmod");
+        /* Don't send our gline as that might cause loops in case we don't understand the gline properly. */
+      } 
+
+      return CMD_OK;
     } else {
       glinebufinit(&gbuf, 0);
       glinebufadd(&gbuf, mask, creator, reason, expire, lastmod, lifetime);
-      glinebufflush(&gbuf, 0);
+      glinebufcommit(&gbuf, 0);
     } 
   } else if (flags & GLINE_DEACTIVATE) {
     /* deactivate gline */
@@ -167,12 +180,22 @@ int handleglinemsg(void *source, int cargc, char **cargv) {
         case 5:
           /* asuka last mod */
           lastmod = atoi(cargv[3]);
-          gline_deactivate(agline, lastmod, 0);
+          
+          if (flags & GLINE_DESTROY)
+            gline_destroy(agline, lastmod, 0);
+          else
+            gline_deactivate(agline, lastmod, 0);
+
           break;
         case 6:
           /* snircd */
           lastmod = atoi(cargv[3]);
-          gline_deactivate(agline, lastmod, 0);
+
+          if (flags & GLINE_DESTROY)
+            gline_destroy(agline, lastmod, 0);
+          else
+            gline_deactivate(agline, lastmod, 0);
+
           break;
         default:
           Error("gline", ERR_WARNING, "Gline Deactivate with invalid number (%d) of arguments", cargc);
@@ -181,13 +204,11 @@ int handleglinemsg(void *source, int cargc, char **cargv) {
 
       return CMD_OK;
     } else {
+       if (cargc < 5)
+         return; /* U:lined gline, we're done */
        Error("gline", ERR_WARNING, "Gline addition - adding deactivated gline - mask not found (%s)", mask);
        expire = abs_expire(atoi(cargv[2]));
        switch (cargc) {
-         case 4:
-           /* asuka U:d, no lastmod */
-           reason = cargv[3];
-           break;
          case 5:
            /*asuka lastmod */
            lastmod = atoi(cargv[3]);
@@ -209,13 +230,13 @@ int handleglinemsg(void *source, int cargc, char **cargv) {
       agline = glinebufadd(&gbuf, mask, creator, reason, expire, lastmod, lifetime);
 
       if (!agline) {
-        glinebufabandon(&gbuf);
+        glinebufabort(&gbuf);
         Error("gline", ERR_WARNING, "gline_add failed");
         return CMD_ERROR;
       }
 
       gline_deactivate(agline, lastmod, 0);
-      glinebufflush(&gbuf, 0);
+      glinebufcommit(&gbuf, 0);
 
       return CMD_OK;
     }
@@ -237,13 +258,12 @@ int handleglinemsg(void *source, int cargc, char **cargv) {
         freesstring(agline->reason);
         agline->reason = getsstring(reason, 255);
       } else {
-        Error("debuggline", ERR_WARNING, "received a gline modification with a lower lastmod");
-        /* @@@TODO resend our gline ? */
+        Debug("received a gline modification with a lower lastmod");
       }
 
       return CMD_OK;
     } else {
-      Error("gline", ERR_WARNING, "Received modification for G-Line that does not exist for mask %s", mask);
+      Debug("Received modification for G-Line that does not exist for mask %s", mask);
       return CMD_ERROR;
     }
   }