Quellcode durchsuchen

Merge branch 'bantype'

* bantype:
  * Cleanup code to avoid constness problems/compile errors
  * Use the channel ban-type for +k/kickban/misc bans in channels
  * cmd_adduser and msd_ident now add hosts with ban-type 0 (*!user@host.com)
  * Add chanint 'ban-type' with a default of 3
  * Bring over bantype patch from eggdrop submitted patch
Bryan Drewery vor 16 Jahren
Ursprung
Commit
fb9772e1c8

+ 1 - 0
doc/UPDATES

@@ -60,6 +60,7 @@
   * Fix cmd_slowjoin not working on backup bots correctly.
   * Fix cmd_slowjoin not working on backup bots correctly.
   * Fix a crash from long hubnicks.
   * Fix a crash from long hubnicks.
 * Misc changes
 * Misc changes
+  * Add new channel setting 'ban-type' which support mIRC style ban types (adapted from recent eggdrop patch)
   * EFnet server list updates (To update yours: .set -YES servers - | .set -YES servers6 -)
   * EFnet server list updates (To update yours: .set -YES servers - | .set -YES servers6 -)
   * Give localhubs credit for adding their child bots in 'whois'.
   * Give localhubs credit for adding their child bots in 'whois'.
   * Ident lookup timeout is now 5 seconds (will speed up linking / partyline connecting)
   * Ident lookup timeout is now 5 seconds (will speed up linking / partyline connecting)

+ 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

+ 1 - 0
src/chan.h

@@ -176,6 +176,7 @@ struct chanset_t {
   int mdop;
   int mdop;
   int mop;
   int mop;
   int voice_non_ident;
   int voice_non_ident;
+  int ban_type;
   interval_t auto_delay;
   interval_t auto_delay;
   int knock_flags;
   int knock_flags;
 /* Chanint template 
 /* Chanint template 

+ 112 - 88
src/misc.c

@@ -207,102 +207,126 @@ char *newsplit(char **rest, char delim, bool trim)
   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 const char *u = NULL, *h = NULL, *p = NULL;
+
+  /* Look for user and host.. */
+  if ((u = strchr(s, '!')))
+    h = strchr(u, '@');
+
+  if (!h)
+    h = strchr(s, '@');
 
 
-  *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 : s);
+  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 : s);
+  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

@@ -28,7 +28,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);

+ 1 - 0
src/mod/channels.mod/cmdschan.c

@@ -1276,6 +1276,7 @@ static void cmd_chaninfo(int idx, char *par)
     SHOW_INT("Auto-delay: ", chan->auto_delay, NULL, "None");
     SHOW_INT("Auto-delay: ", chan->auto_delay, NULL, "None");
     SHOW_INT("Bad-cookie:" , chan->bad_cookie, P_STR, "Ignore");
     SHOW_INT("Bad-cookie:" , chan->bad_cookie, P_STR, "Ignore");
     SHOW_INT("Ban-time: ", chan->ban_time, NULL, "Forever");
     SHOW_INT("Ban-time: ", chan->ban_time, NULL, "Forever");
+    SHOW_INT("Ban-type: ", chan->ban_type, NULL, "3");
     SHOW_INT("Closed-ban: ", chan->closed_ban, NULL, "Don't!");
     SHOW_INT("Closed-ban: ", chan->closed_ban, NULL, "Don't!");
     SHOW_INT("Closed-invite:", chan->closed_invite, NULL, "Don't!");
     SHOW_INT("Closed-invite:", chan->closed_invite, NULL, "Don't!");
     SHOW_INT("Closed-Private:", chan->closed_private, NULL, "Don't!");
     SHOW_INT("Closed-Private:", chan->closed_private, NULL, "Don't!");

+ 9 - 0
src/mod/channels.mod/tclchan.c

@@ -536,6 +536,14 @@ int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
         return ERROR;
         return ERROR;
       }
       }
       chan->auto_delay = atoi(item[i]);
       chan->auto_delay = atoi(item[i]);
+    } else if (!strcmp(item[i], "ban-type")) {
+      i++;
+      if (i >= items) {
+        if (result)
+          strlcpy(result, "channel ban-type needs argument", RESULT_LEN);
+        return ERROR;
+      }
+      chan->ban_type = atoi(item[i]);
      
      
 
 
 /* Chanint template
 /* Chanint template
@@ -946,6 +954,7 @@ int channel_add(char *result, char *newname, char *options)
     chan->closed_invite = 1;
     chan->closed_invite = 1;
     chan->voice_non_ident = 1;
     chan->voice_non_ident = 1;
     chan->auto_delay = 5;
     chan->auto_delay = 5;
+    chan->ban_type = 3;
 /* Chanint template
 /* Chanint template
  *  chan->temp = 0;
  *  chan->temp = 0;
  */
  */

+ 2 - 1
src/mod/channels.mod/userchan.c

@@ -726,7 +726,7 @@ void write_chans(bd::Stream& stream, int idx)
 
 
     stream << buf.printf("\
     stream << buf.printf("\
 + channel add %s { chanmode { %s } addedby %s addedts %li \
 + channel add %s { chanmode { %s } addedby %s addedts %li \
-bad-cookie %d manop %d mdop %d mop %d limit %d \
+bad-cookie %d manop %d mdop %d mop %d limit %d ban-type %d \
 flood-chan %d:%d flood-ctcp %d:%d flood-join %d:%d \
 flood-chan %d:%d flood-ctcp %d:%d flood-join %d:%d \
 flood-kick %d:%d flood-deop %d:%d flood-nick %d:%d flood-mjoin %d:%d \
 flood-kick %d:%d flood-deop %d:%d flood-nick %d:%d flood-mjoin %d:%d \
 closed-ban %d closed-invite %d closed-private %d ban-time %d \
 closed-ban %d closed-invite %d closed-private %d ban-time %d \
@@ -749,6 +749,7 @@ flood-exempt %d flood-lock-time %d knock %d \
 	chan->mdop,
 	chan->mdop,
 	chan->mop,
 	chan->mop,
         chan->limitraise,
         chan->limitraise,
+        chan->ban_type,
 	chan->flood_pub_thr, chan->flood_pub_time,
 	chan->flood_pub_thr, chan->flood_pub_time,
         chan->flood_ctcp_thr, chan->flood_ctcp_time,
         chan->flood_ctcp_thr, chan->flood_ctcp_time,
         chan->flood_join_thr, chan->flood_join_time,
         chan->flood_join_thr, chan->flood_join_time,

+ 1 - 1
src/mod/irc.mod/chan.c

@@ -741,7 +741,7 @@ static char *quickban(struct chanset_t *chan, char *uhost)
 {
 {
   static char s1[512] = "";
   static char s1[512] = "";
 
 
-  maskhost(uhost, s1);
+  maskaddr(uhost, s1, chan->ban_type);
   /* this used to only happen with strict_host == 0 */
   /* this used to only happen with strict_host == 0 */
   if (strlen(s1) != 1)
   if (strlen(s1) != 1)
     s1[2] = '*';		/* arthur2 */
     s1[2] = '*';		/* arthur2 */

+ 1 - 1
src/mod/irc.mod/cmdsirc.c

@@ -1778,7 +1778,7 @@ static void cmd_adduser(int idx, char *par)
     return;
     return;
   }
   }
   if (!statichost)
   if (!statichost)
-    maskhost(s, s1);
+    maskaddr(s, s1, 0); /* *!user@host.com */
   else {
   else {
     strlcpy(s1, s, sizeof s1);
     strlcpy(s1, s, sizeof s1);
     p1 = strchr(s1, '!');
     p1 = strchr(s1, '!');

+ 1 - 1
src/mod/irc.mod/msgcmds.c

@@ -216,7 +216,7 @@ static int msg_ident(char *nick, char *host, struct userrec *u, char *par)
     } else {
     } else {
       putlog(LOG_CMDS, "*", "(%s!%s) !*! IDENT %s", nick, host, who);
       putlog(LOG_CMDS, "*", "(%s!%s) !*! IDENT %s", nick, host, who);
       simple_snprintf(s, sizeof s, "%s!%s", nick, host);
       simple_snprintf(s, sizeof s, "%s!%s", nick, host);
-      maskhost(s, s1);
+      maskaddr(s, s1, 0); /* *!user@host */
       dprintf(DP_HELP, "NOTICE %s :Added hostmask: %s\n", nick, s1);
       dprintf(DP_HELP, "NOTICE %s :Added hostmask: %s\n", nick, s1);
       addhost_by_handle(who, s1);
       addhost_by_handle(who, s1);
       check_this_user(who, 0, NULL);
       check_this_user(who, 0, NULL);

+ 1 - 1
src/set.c

@@ -40,7 +40,7 @@ int dcc_autoaway;
 bool irc_autoaway;
 bool irc_autoaway;
 bool link_cleartext;
 bool link_cleartext;
 bool dccauth = 0;
 bool dccauth = 0;
-char *def_chanset = "+enforcebans +dynamicbans +userbans -bitch +cycle -inactive +userexempts -dynamicexempts +userinvites -dynamicinvites -nodesynch -closed -take -voice -private -fastop +meankicks";
+char *def_chanset = "+enforcebans +dynamicbans +userbans -bitch +cycle -inactive +userexempts -dynamicexempts +userinvites -dynamicinvites -nodesynch -closed -take -voice -private -fastop +meankicks ban-type 3";
 int cloak_script = 0;
 int cloak_script = 0;
 rate_t close_threshold;
 rate_t close_threshold;
 int fight_threshold;
 int fight_threshold;