added basic ssl support to ircu
[ircu2.10.12-pk.git] / ircd / m_silence.c
index 97069d4d9552de5ec0360873ee48e63bd5abd0fd..ce9d4dc5ed58d63738f446cc68a1f32020ee2019 100644 (file)
@@ -64,6 +64,8 @@ apply_silence(struct Client *sptr, char *mask)
 {
   struct Ban *sile;
   int flags;
+  int res;
+  char orig_mask[NICKLEN+USERLEN+HOSTLEN+3];
 
   assert(mask && mask[0]);
 
@@ -83,10 +85,24 @@ apply_silence(struct Client *sptr, char *mask)
     mask++;
   }
 
-  /* Make the silence, set flags, and apply it. */
+  /* Make the silence and set additional flags. */
+  ircd_strncpy(orig_mask, mask, sizeof(orig_mask) - 1);
   sile = make_ban(pretty_mask(mask));
   sile->flags |= flags;
-  return apply_ban(&cli_user(sptr)->silence, sile, 1) ? NULL : sile;
+
+  /* If they're a local user trying to ban too broad a mask, forbid it. */
+  if (MyUser(sptr)
+      && (sile->flags & BAN_IPMASK)
+      && sile->addrbits > 0
+      && sile->addrbits < (irc_in_addr_is_ipv4(&sile->address) ? 112 : 32)) {
+    send_reply(sptr, ERR_MASKTOOWIDE, orig_mask);
+    free_ban(sile);
+    return NULL;
+  }
+
+  /* Apply it to the silence list. */
+  res = apply_ban(&cli_user(sptr)->silence, sile, 1);
+  return res ? NULL : sile;
 }
 
 /** Apply and send silence updates for a user.
@@ -109,7 +125,6 @@ forward_silences(struct Client *sptr, char *silences, struct Client *dest)
       accepted[ac_count++] = sile;
   }
 
-
   if (MyUser(sptr)) {
     size_t siles, maxsiles, totlength, maxlength, jj;
 
@@ -244,8 +259,9 @@ forward_silences(struct Client *sptr, char *silences, struct Client *dest)
 
   /* Free any silence-deleting updates. */
   for (ii = 0; ii < ac_count; ++ii) {
-    if (accepted[ii]->flags & BAN_DEL)
+    if ((accepted[ii]->flags & (BAN_ADD | BAN_DEL)) == BAN_DEL) {
       free_ban(accepted[ii]);
+    }
   }
 }
 
@@ -273,7 +289,7 @@ int m_silence(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
   /* See if the user is requesting a silence list. */
   acptr = sptr;
   if (parc < 2 || EmptyString(parv[1]) || (acptr = FindUser(parv[1]))) {
-    if (cli_user(acptr)) {
+    if (cli_user(acptr) && ((acptr == sptr) || IsChannelService(acptr))) {
       for (sile = cli_user(acptr)->silence; sile; sile = sile->next) {
         send_reply(sptr, RPL_SILELIST, cli_name(acptr),
                    (sile->flags & BAN_EXCEPTION ? "~" : ""),  sile->banstr);