فهرست منبع

* Bring over bantype patch from eggdrop submitted patch

This patch provides customizable host masking, compatible and extending
mIRC's mask types. Users will be able to make use of this trough a new
channel setting "ban-type".
-Rumen Stoyanov
Rumen Stoyanov (Ported by Bryan) 17 سال پیش
والد
کامیت
7b83e9d675
3فایلهای تغییر یافته به همراه135 افزوده شده و 89 حذف شده
  1. 17 0
      doc/help.txt
  2. 115 88
      src/misc.c
  3. 3 1
      src/misc.h

+ 17 - 0
doc/help.txt

@@ -380,6 +380,23 @@ See also: link
         $bban-time$b          Set here how long temporary bans will last (in
         $bban-time$b          Set here how long temporary bans will last (in
                           minutes). If you set this setting to 0, the bot will
                           minutes). If you set this setting to 0, the bot will
                           never remove them. (This also requires +dynamicbans)
                           never remove them. (This also requires +dynamicbans)
+        $bban-type$b
+                              This setting defines what type of bans should be
+                          placed. Available types are:
+                              0 *!user@host
+                              1 *!*user@host
+                              2 *!*@host
+                              3 *!*user@*.host
+                              4 *!*@*.host
+                              5 nick!user@host
+                              6 nick!*user@host
+                              7 nick!*@host
+                              8 nick!*user@*.host
+                              9 nick!*@*.host
+                          You can also specify types from 10 to 19 which correspond
+                          to types 0 to 9, with the exception that numbers in hostnames
+                          are replaced with the '?' wildcard, or 20 to 29, which works
+                          like 10 to 19 but using '*' for numbers, instead of '?'.
         $bexempt-time$b       Set here how long temporary exempts will last (in
         $bexempt-time$b       Set here how long temporary exempts will last (in
                           minutes). If you set this setting to 0, the bot will
                           minutes). If you set this setting to 0, the bot will
                           never remove them. The bot will check the exempts
                           never remove them. The bot will check the exempts

+ 115 - 88
src/misc.c

@@ -197,102 +197,129 @@ char *newsplit(char **rest)
   return r;
   return r;
 }
 }
 
 
-/* Convert "abc!user@a.b.host" into "*!user@*.b.host"
- * or "abc!user@1.2.3.4" into "*!user@1.2.3.*"
- * or "abc!user@0:0:0:0:0:ffff:1.2.3.4" into "*!user@0:0:0:0:0:ffff:1.2.3.*"
- * or "abc!user@3ffe:604:2:b02e:6174:7265:6964:6573" into
- *    "*!user@3ffe:604:2:b02e:6174:7265:6964:*"
+/* maskhost(), modified to support custom mask types, as defined
+ * by mIRC.
+ * Does not require a proper hostmask in 's'. Accepts any strings,
+ * including empty ones and attempts to provide meaningful results.
+ *
+ * Strings containing no '@' character will be parsed as if the
+ * whole string is a host.
+ * Strings containing no '!' character will be interpreted as if
+ * there is no nick.
+ * '!' as a nick/user separator must precede any '@' characters.
+ * Otherwise it will be considered a part of the host.
+ * Supported types are listed in tcl-commands.doc in the maskhost
+ * command section. Type 3 resembles the older maskhost() most closely.
+ *
+ * Specific examples (with type=3):
+ *
+ * "nick!user@is.the.lamest.bg"  -> *!*user@*.the.lamest.bg (ccTLD)
+ * "nick!user@is.the.lamest.com" -> *!*user@*.lamest.com (gTLD)
+ * "lamest.example"              -> *!*@lamest.example
+ * "whatever@lamest.example"     -> *!*whatever@lamest.example
+ * "com.example@user!nick"       -> *!*com.example@user!nick
+ * "!"                           -> *!*@!
+ * "@"                           -> *!*@*
+ * ""                            -> *!*@*
+ * "abc!user@2001:db8:618:5c0:263:15:dead:babe"
+ * -> *!*user@2001:db8:618:5c0:263:15:dead:*
+ * "abc!user@0:0:0:0:0:ffff:1.2.3.4"
+ * -> *!*user@0:0:0:0:0:ffff:1.2.3.*
  */
  */
-void maskhost(const char *s, char *nw)
+void maskaddr(const char *s, char *nw, int type)
 {
 {
-  register const char *p, *q, *e, *f;
-  int i;
+  int d = type % 5, num = 1;
+  register char *p, *u = 0, *h = 0, *ss;
+
+  /* Look for user and host.. */
+  ss = (char *)s;
+  u = strchr(s, '!');
+  if (u)
+    h = strchr(u, '@');
+  if (!h){
+    h = strchr(s, '@');
+    u = 0;
+  }
 
 
-  *nw++ = '*';
+  /* Print nick if required and available */
+  if (!u || (type % 10) < 5)
+    *nw++ = '*';
+  else {
+    strncpy(nw, s, u - s);
+    nw += u - s;
+  }
   *nw++ = '!';
   *nw++ = '!';
-  p = (q = strchr(s, '!')) ? q + 1 : s;
-  /* Strip of any nick, if a username is found, use last 8 chars */
-  if ((q = strchr(p, '@'))) {
-    int fl = 0;
-
-    if ((q - p) > 9) {
-      nw[0] = '*';
-      p = q - 7;
-      i = 1;
-    } else
-      i = 0;
-    while (*p != '@') {
-      if (!fl && strchr("~+-^=", *p))
-       nw[i] = '?';
-      else
-        nw[i] = *p;
-      fl++;
-      p++;
-      i++;
+
+  /* Write user if required and available */
+  u = (u ? u + 1 : ss);
+  if (!h || (d == 2) || (d == 4))
+    *nw++ = '*';
+  else {
+    if (d) {
+      *nw++ = '*';
+      if (strchr("~+-^=", *u))
+        u++; /* trim leading crap */
     }
     }
-    nw[i++] = '@';
-    q++;
-  } else {
-    nw[0] = '*';
-    nw[1] = '@';
-    i = 2;
-    q = s;
+    strncpy(nw, u, h - u);
+    nw += h - u;
   }
   }
-  nw += i;
-  e = NULL;
-  /* Now q points to the hostname, i point to where to put the mask */
-  if ((!(p = strchr(q, '.')) || !(e = strchr(p + 1, '.'))) && !strchr(q, ':'))
-    /* TLD or 2 part host */
-    strcpy(nw, q);
-  else {
-    if (e == NULL) {		/* IPv6 address?		*/
-      const char *mask_str;
-
-      f = strrchr(q, ':');
-      if (strchr(f, '.')) {	/* IPv4 wrapped in an IPv6?	*/
-	f = strrchr(f, '.');
-	mask_str = ".*";
-      } else 			/* ... no, true IPv6.		*/
-	mask_str = ":*";
-      strncpy(nw, q, f - q);
-      /* No need to nw[f-q] = 0 here, as the strcpy below will
-       * terminate the string for us.
-       */
-      nw += (f - q);
-      strcpy(nw, mask_str);
-    } else {
-      for (f = e; *f; f++)
-        ;
-      f--;
-      if (*f >= '0' && *f <= '9') {	/* Numeric IP address */
-	while (*f != '.')
-	  f--;
-	strncpy(nw, q, f - q);
-	/* No need to nw[f-q] = 0 here, as the strcpy below will
-	 * terminate the string for us.
-	 */
-	nw += (f - q);
-	strcpy(nw, ".*");
-      } else {				/* Normal host >= 3 parts */
-	/*    a.b.c  -> *.b.c
-	 *    a.b.c.d ->  *.b.c.d if tld is a country (2 chars)
-	 *             OR   *.c.d if tld is com/edu/etc (3 chars)
-	 *    a.b.c.d.e -> *.c.d.e   etc
-	 */
-	const char *x = strchr(e + 1, '.');
-
-	if (!x)
-	  x = p;
-	else if (strchr(x + 1, '.'))
-	  x = e;
-	else if (strlen(x) == 3)
-	  x = p;
-	else
-	  x = e;
-	simple_sprintf(nw, "*%s", x);
+  *nw++ = '@';
+
+  /* The rest is for the host */
+  h = (h ? h + 1 : ss);
+  for (p = h; *p; p++) /* hostname? */
+    if ((*p > '9' || *p < '0') && *p != '.') {
+      num = 0;
+      break;
+    }
+  p = strrchr(h, ':'); /* IPv6? */
+  /* Mask out after the last colon/dot */
+  if (p && d > 2) {
+    if ((u = strrchr(p, '.')))
+      p = u;
+    strncpy(nw, h, ++p - h);
+    nw += p - h;
+    strcpy(nw, "*");
+  } else if (!p && !num && type >= 10) {
+      /* we have a hostname and type
+       requires us to replace numbers */
+    num = 0;
+    for (p = h; *p; p++) {
+      if (*p < '0' || *p > '9') {
+        *nw++ = *p;
+        num = 0;
+      } else {
+        if (type < 20)
+          *nw++ = '?';
+        else if (!num) {
+          *nw++ = '*';
+          num = 1; /* place only one '*'
+                      per numeric sequence */
+        }
       }
       }
     }
     }
-  }
+    *nw = 0;
+  } else if (d > 2 && (p = strrchr(h, '.'))) {
+    if (num) { /* IPv4 */
+      strncpy(nw, h, p - h);
+      nw += p - h;
+      strcpy(nw, ".*");
+      return;
+    }
+    for (u = h, d = 0; (u = strchr(++u, '.')); d++) ;
+    if (d < 2) { /* types < 2 don't mask the host */
+      strcpy(nw, h);
+      return;
+    }
+    u = strchr(h, '.');
+    if (d > 3 || (d == 3 && strlen(p) > 3))
+      u = strchr(++u, '.'); /* ccTLD or not? Look above. */
+    simple_sprintf(nw, "*%s", u);
+  } else if (!*h) {
+    /* take care if the mask is empty or contains only '@' */
+    strcpy(nw, "*");
+  } else
+    strcpy(nw, h);
 }
 }
 
 
 
 

+ 3 - 1
src/misc.h

@@ -25,7 +25,9 @@ int bot_aggressive_to(struct userrec *);
 void readsocks(const char *);
 void readsocks(const char *);
 int updatebin(int, char *, int);
 int updatebin(int, char *, int);
 size_t my_strcpy(char *, const char *);
 size_t my_strcpy(char *, const char *);
-void maskhost(const char *, char *);
+void maskaddr(const char *, char *, int);
+#define maskhost(a,b) maskaddr((a),(b),3)
+#define maskban(a,b)  maskaddr((a),(b),3)
 char *stristr(char *, char *);
 char *stristr(char *, char *);
 void splitc(char *, char *, char);
 void splitc(char *, char *, char);
 void splitcn(char *, char *, char, size_t);
 void splitcn(char *, char *, char, size_t);