]> jfr.im git - irc/quakenet/newserv.git/commitdiff
Merge.
authorGunnar Beutner <redacted>
Sat, 21 Jun 2014 14:48:49 +0000 (16:48 +0200)
committerGunnar Beutner <redacted>
Sat, 21 Jun 2014 14:48:49 +0000 (16:48 +0200)
chanserv/authlib.c
chanserv/authlib.h
chanserv/chanserv.h
glines/glines_handler.c
newsearch/newsearch.c
newsearch/ns-gline.c
patricia/patricialib.c
whowas/whowas.c
whowas/whowas.h
whowas/whowas_commands.c

index 3f4026fd08f428df9ea3bbe9c7ffb870586f57ee..09733b614f3df843b5d494214b0d0d6cc8a76fc4 100644 (file)
@@ -8,34 +8,24 @@
 #include <string.h>
 #include <ctype.h>
 #include <sys/types.h>
-#include <regex.h>
+#include <pcre.h>
 
-regex_t remail, raccount;
-static int regexinit;
+static pcre *remail, *raccount;
 
-int csa_initregex(void) {
-  if (regexinit)
-    return 1;
+void csa_initregex(void) {
+  const char *errptr;
+  int erroffset;
 
-  if (regcomp(&remail, VALID_EMAIL, REG_EXTENDED | REG_NOSUB | REG_ICASE))
-    return 0;
+  if (!(remail=pcre_compile(VALID_EMAIL, PCRE_CASELESS, &errptr, &erroffset, NULL)))
+    Error("chanserv", ERR_STOP, "Unable to compile email regex (error: %s, position: %d).", errptr, erroffset);
 
-  if (regcomp(&raccount, VALID_ACCOUNT_NAME, REG_EXTENDED | REG_NOSUB | REG_ICASE)) {
-    regfree(&remail);
-    return 0;
-  }
-
-  regexinit = 1;
-  return 1;
+  if (!(raccount=pcre_compile(VALID_ACCOUNT_NAME, PCRE_CASELESS, &errptr, &erroffset, NULL)))
+    Error("chanserv", ERR_STOP, "Unable to compile account name regex (error: %s, position: %d).", errptr, erroffset);
 }
 
 void csa_freeregex(void) {
-  if(!regexinit)
-    return;
-
-  regfree(&remail);
-  regfree(&raccount);
-  regexinit = 0;
+  pcre_free(remail);
+  pcre_free(raccount);
 }
 
 /*
@@ -43,29 +33,13 @@ void csa_freeregex(void) {
  */
 int csa_checkeboy_r(char *eboy)
 {
-  int i, len;
+  int len;
 
   len = (((strlen(eboy)) < (EMAILLEN)) ? (strlen(eboy)) : (EMAILLEN));
   if (len <= 4) {
     return QM_EMAILTOOSHORT;
   }
 
-  if (strstr(&eboy[1], "@") == NULL) {
-    return QM_EMAILNOAT;
-  }
-
-  if (eboy[len - 1] == '@') {
-    return QM_EMAILATEND;
-  }
-
-  for (i = 0; i < len; i++) {
-    if (!isalpha(eboy[i]) && !isdigit(eboy[i])
-        && !(eboy[i] == '@') && !(eboy[i] == '.')
-        && !(eboy[i] == '_') && !(eboy[i] == '-')) {
-      return QM_EMAILINVCHR;
-    }
-  }
-
   /* catch some real lame attempts */
   if (!ircd_strncmp("user@mymailhost.xx", eboy, len) || !ircd_strncmp("info@quakenet.org", eboy, len)
       || !ircd_strncmp("user@mymail.xx", eboy, len) || !ircd_strncmp("user@mail.cc", eboy, len)
@@ -75,7 +49,7 @@ int csa_checkeboy_r(char *eboy)
     return QM_NOTYOUREMAIL;
   }
 
-  if (regexec(&remail, eboy, (size_t) 0, NULL, 0)) {
+  if (pcre_exec(remail, NULL, eboy, strlen(eboy), 0, 0, NULL, 0) < 0) {
     return QM_INVALIDEMAIL;
   }
 
@@ -96,9 +70,10 @@ int csa_checkeboy(nick *sender, char *eboy)
 
 /*
  * use regex matching to determine if it's a valid account name or not
+ * returns 1 if bad, 0 if good
  */
 int csa_checkaccountname_r(char *accountname) {
-  if (regexec(&raccount, accountname, (size_t) 0, NULL, 0)) {
+  if (pcre_exec(raccount, NULL, accountname, strlen(accountname), 0, 0, NULL, 0) < 0) {
     return (1);
   }
   return (0);
index 5349c72f130a1913ee4f8a4c9b75b5c947dbb5ab..06093067243fe32c4b6b2ec6c13eaa57e343ed91 100644 (file)
@@ -5,7 +5,7 @@
 /* Functions in authlib.c */
 int cs_checkeboy(nick *np, char *arg);
 void cs_createrandompw(char *arg, int n);
-int csa_initregex(void);
+void csa_initregex(void);
 void csa_freeregex(void);
 int csa_checkaccountname(nick *sender, char *accountname);
 int csa_checkaccountname_r(char *accountname);
index c8ddfc1ca13e05d50dd88ff5c6f4d9737dd40a6d..45f6dfc41f5c33db47d2756691baff89553e48c2 100644 (file)
 
 /* email */
 #define MAX_RESEND_TIME      2*3600L  /* cooling off period */
-#define VALID_EMAIL         "^[-_.+[:alpha:][:digit:]]+(\\.[-_[:digit:][:alpha:]]+)*@([[:digit:][:alpha:]](-?[[:digit:][:alpha:]])*\\.)+[[:alpha:]]{2}([zmuvtgol]|fo|me|seum|op|ro)?$"
+#define VALID_EMAIL         "\\A[^\\s\\+@]+@([a-z0-9][a-z0-9\\-]*\\.)+[a-z]{2,}\\Z"
 
-#define VALID_ACCOUNT_NAME  "^[a-z][-a-z0-9]+$"
+#define VALID_ACCOUNT_NAME  "\\A[a-z][a-z0-9\\-]+\\Z"
 
 #define QMAIL_NEWACCOUNT           1  /* new account */
 #define QMAIL_REQPW                2  /* requestpassword */
index 6ff22a7ebf62ac5ecec85d631ecad4a34ce66585..e32d20f8d4b1b59c842ce89b9eac4c4f679bfb8d 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>]
 */
@@ -130,12 +138,12 @@ 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) {
-      Error("debuggline", ERR_WARNING, "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);
+      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;
 
@@ -149,7 +157,7 @@ int handleglinemsg(void *source, int cargc, char **cargv) {
         freesstring(agline->reason);
         agline->reason = getsstring(reason, 255); 
       } else {
-        Error("debuggline", ERR_WARNING, "received a gline with a lower lastmod");
+        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. */
       } 
 
@@ -252,12 +260,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");
+        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;
     }
   }
index 083723df6e9dfe02833facc4f2195c89c8f6fa43..3d4e46f93ad8a74cd865fdd251ef0b0802259b64 100644 (file)
@@ -634,8 +634,8 @@ void whowassearch_exe(struct searchNode *search, searchCtx *ctx) {
   /* The top-level node needs to return a BOOL */
   search=coerceNode(ctx, search, RETURNTYPE_BOOL);
 
-  for (i = whowasoffset; i < whowasoffset + WW_MAXENTRIES; i++) {
-    ww = &whowasrecs[i % WW_MAXENTRIES];
+  for (i = whowasoffset; i < whowasoffset + whowasmax; i++) {
+    ww = &whowasrecs[i % whowasmax];
 
     if (ww->type == WHOWAS_UNUSED)
       continue;
index f366fd33f022be2ec98fa7b491d261f7db2a63be..f989633dd1c793347fe64875426ef831e7964c51 100644 (file)
@@ -215,8 +215,8 @@ void gline_free(searchCtx *ctx, struct searchNode *thenode) {
       }
     }
   } else {
-    for (i = whowasoffset; i < whowasoffset + WW_MAXENTRIES; i++) {
-      ww = &whowasrecs[i % WW_MAXENTRIES];
+    for (i = whowasoffset; i < whowasoffset + whowasmax; i++) {
+      ww = &whowasrecs[i % whowasmax];
 
       if (ww->type == WHOWAS_UNUSED)
         continue;
index 009b1dbcb704cbf96c42e7fadb40a970ede129f9..86584c342add2f44863660c2f30c98e54639d2c9 100644 (file)
@@ -27,6 +27,18 @@ char patricia_copyright[] =
 
 #include "patricia.h"
 
+//#define LEAK_DETECTION
+
+#ifdef LEAK_DETECTION
+#define MAGIC 0x6a3b4ef3
+
+struct fake_node {
+  patricia_node_t node;
+  uint32_t magic;
+  patricia_node_t *real_node;
+};
+#endif
+
 /* prefix_tochar
  * convert prefix information to bytes
  */
@@ -531,6 +543,16 @@ patricia_remove (patricia_tree_t *patricia, patricia_node_t *node)
     }
 }
 
+#ifdef LEAK_DETECTION
+static patricia_node_t *getrealnode(patricia_node_t *node) {
+  struct fake_node *f = (struct fake_node *)node;
+  if(f->magic != MAGIC) {
+    printf("magic failure\n");
+    abort();
+  }
+  return f->real_node;
+}
+#endif
 
 patricia_node_t *
 refnode(patricia_tree_t *tree, struct irc_in_addr *sin, int bitlen) {
@@ -547,6 +569,14 @@ refnode(patricia_tree_t *tree, struct irc_in_addr *sin, int bitlen) {
     patricia_ref_prefix(node->prefix);
   }
 
+#ifdef LEAK_DETECTION
+  struct fake_node *f = malloc(sizeof(struct fake_node));
+  f->magic = MAGIC;
+  f->node = *node;
+  f->real_node = node;
+  node = (patricia_node_t *)f;
+#endif
+
   return node;
 }
 
@@ -555,6 +585,15 @@ derefnode(patricia_tree_t *tree, patricia_node_t *node) {
   if (!node || !node->prefix)
     return;
 
+#ifdef LEAK_DETECTION
+  patricia_node_t *real_node = getrealnode(node);
+  free(node);
+  node = real_node;
+
+  if (!node || !node->prefix)
+    return;
+#endif
+
   if (node->prefix->ref_count == 1) {
     patricia_remove(tree, node);
   } else
@@ -574,6 +613,10 @@ patricia_node_t *patricia_new_node(patricia_tree_t *patricia, unsigned char bit,
 }
 
 void node_increment_usercount( patricia_node_t *node) {
+#ifdef LEAK_DETECTION
+  node = getrealnode(node);
+#endif
+
   while(node) {
     node->usercount++;
     node=node->parent;
@@ -581,6 +624,10 @@ void node_increment_usercount( patricia_node_t *node) {
 }
 
 void node_decrement_usercount( patricia_node_t *node) {
+#ifdef LEAK_DETECTION
+  node = getrealnode(node);
+#endif
+
   while(node) {
     node->usercount--;
     node=node->parent;
index 5764ecac0bd154b3a9e5da11d1a6741796f77f53..9e2cdb3c74d6f9e753a3e3445a24a2549e514a51 100644 (file)
@@ -5,12 +5,14 @@
 #include "../irc/irc.h"
 #include "../lib/irc_string.h"
 #include "../lib/version.h"
+#include "../core/config.h"
 #include "whowas.h"
 
 MODULE_VERSION("");
 
-whowas whowasrecs[WW_MAXENTRIES];
+whowas *whowasrecs;
 int whowasoffset = 0;
+int whowasmax;
 
 whowas *whowas_fromnick(nick *np, int standalone) {
   whowas *ww;
@@ -24,7 +26,7 @@ whowas *whowas_fromnick(nick *np, int standalone) {
   else {
     ww = &whowasrecs[whowasoffset];
     whowas_clean(ww);
-    whowasoffset = (whowasoffset + 1) % WW_MAXENTRIES;
+    whowasoffset = (whowasoffset + 1) % whowasmax;
   }
 
   memset(ww, 0, sizeof(whowas));
@@ -92,8 +94,9 @@ void whowas_clean(whowas *ww) {
   freesstring(np->opername);
   freeauthname(np->auth);
   freesstring(np->away);
-
+  derefnode(iptree, np->ipnode);
   freesstring(ww->reason);
+  freesstring(ww->newnick);
   ww->type = WHOWAS_UNUSED;
 }
 
@@ -152,8 +155,8 @@ whowas *whowas_chase(const char *target, int maxage) {
 
   now = getnettime();
 
-  for (i = whowasoffset + WW_MAXENTRIES - 1; i >= whowasoffset; i--) {
-    ww = &whowasrecs[i % WW_MAXENTRIES];
+  for (i = whowasoffset + whowasmax - 1; i >= whowasoffset; i--) {
+    ww = &whowasrecs[i % whowasmax];
 
     if (ww->type == WHOWAS_UNUSED)
       continue;
@@ -226,8 +229,8 @@ unsigned int nextwhowasmarker() {
 
   if (!whowasmarker) {
     /* If we wrapped to zero, zap the marker on all records */
-    for (i = 0; i < WW_MAXENTRIES; i++) {
-      ww = &whowasrecs[i % WW_MAXENTRIES];
+    for (i = 0; i < whowasmax; i++) {
+      ww = &whowasrecs[i % whowasmax];
       ww->marker=0;
     }
 
@@ -238,7 +241,12 @@ unsigned int nextwhowasmarker() {
 }
 
 void _init(void) {
-  memset(whowasrecs, 0, sizeof(whowasrecs));
+  {
+    sstring *temp = getcopyconfigitem("whowas", "maxentries", XStringify(WW_DEFAULT_MAXENTRIES), 10);
+    whowasmax = atoi(temp->content);
+    freesstring(temp);
+  }
+  whowasrecs = calloc(whowasmax, sizeof(whowas));
 
   registerhook(HOOK_NICK_QUIT, whowas_handlequitorkill);
   registerhook(HOOK_NICK_KILL, whowas_handlequitorkill);
@@ -253,8 +261,10 @@ void _fini(void) {
   deregisterhook(HOOK_NICK_KILL, whowas_handlequitorkill);
   deregisterhook(HOOK_NICK_RENAME, whowas_handlerename);
 
-  for (i = 0; i < WW_MAXENTRIES; i++) {
+  for (i = 0; i < whowasmax; i++) {
     ww = &whowasrecs[i];
     whowas_clean(ww);
   }
+
+  free(whowasrecs);
 }
index a9561d106f4e0a07d903902d6ff8d3c1bb277121..5c02bde0e27ed1ec8f815cc582039590b84ecc90 100644 (file)
@@ -2,7 +2,7 @@
 #define __WHOWAS_H
 
 #define WW_MAXCHANNELS 20
-#define WW_MAXENTRIES 1000000
+#define WW_DEFAULT_MAXENTRIES 1000
 #define WW_MASKLEN (HOSTLEN + USERLEN + NICKLEN)
 #define WW_REASONLEN 512
 
@@ -24,7 +24,8 @@ typedef struct whowas {
   struct whowas *prev;
 } whowas;
 
-extern whowas whowasrecs[WW_MAXENTRIES];
+extern whowas *whowasrecs;
+extern int whowasmax;
 extern int whowasoffset; /* points to oldest record */
 
 #define WHOWAS_UNUSED 0
index 50337b4c52a9704f2f138abba0ddc6bfeaa38c91..db688ae29dfd2de7759e958821710a72bd35bba6 100644 (file)
@@ -26,8 +26,8 @@ static int whowas_cmdwhowas(void *source, int cargc, char **cargv) {
   if (cargc > 1)
     limit = strtol(cargv[1], NULL, 10);
 
-  for (i = whowasoffset; i < whowasoffset + WW_MAXENTRIES; i++) {
-    ww = &whowasrecs[i % WW_MAXENTRIES];
+  for (i = whowasoffset; i < whowasoffset + whowasmax; i++) {
+    ww = &whowasrecs[i % whowasmax];
 
     if (ww->type == WHOWAS_UNUSED)
       continue;