]> jfr.im git - irc/rizon/plexus4.git/commitdiff
Add m_highlight to block highlight spam
authorAdam <redacted>
Mon, 10 Jul 2017 15:57:08 +0000 (11:57 -0400)
committerAdam <redacted>
Mon, 10 Jul 2017 15:57:08 +0000 (11:57 -0400)
doc/reference.conf
include/conf.h
modules/Makefile.am
modules/m_highlight.c [new file with mode: 0644]
src/conf.c
src/conf_lexer.l
src/conf_parser.y

index da8f4b090ca16a5e4c63a1f799eef6f2e9fcd001..c9e785b11db0b356f05be667c7eeadca41862f3a 100644 (file)
@@ -1375,6 +1375,12 @@ general {
         *      openssl list-message-digest-algorithms
         */
 #      ssl_message_digest_algorithm = "sha1";
+
+       /*
+        * mass_highlight_nicks: defines how many nicks can be highlighted in a
+        * message before the message is blocked. Set to 0 to disable.
+        */
+#      mass_highlight_nicks = 4;
 };
 
 modules {
index f6b047edf3f2fe65e802871fb5df46709b442583..ac5238c6bb13a06a6dfc08dbddec4d61312ef665 100644 (file)
@@ -288,6 +288,7 @@ struct config_file_entry
   int enable_extbans;
   int enable_forwarding;
   const EVP_MD *message_digest_algorithm;
+  int mass_highlight_nicks;
 };
 
 struct config_channel_entry
index 9a25db9db1ca82bfe86976e71d9f185d54f147d7..a4875af51be324dc32be328a9eaac2a34054ae11 100644 (file)
@@ -35,6 +35,7 @@ modules_LTLIBRARIES = cloak_hmac_sha256.la \
                       m_globops.la   \
                       m_hash.la      \
                       m_help.la      \
+                      m_highlight.la \
                       m_info.la      \
                       m_invite.la    \
                       m_ison.la      \
@@ -120,6 +121,7 @@ m_gline_la_LDFLAGS = $(MODULE_FLAGS)
 m_globops_la_LDFLAGS = $(MODULE_FLAGS)
 m_hash_la_LDFLAGS = $(MODULE_FLAGS)
 m_help_la_LDFLAGS = $(MODULE_FLAGS)
+m_highlight_la_LDFLAGS = $(MODULE_FLAGS)
 m_info_la_LDFLAGS = $(MODULE_FLAGS)
 m_invite_la_LDFLAGS = $(MODULE_FLAGS)
 m_ison_la_LDFLAGS = $(MODULE_FLAGS)
@@ -204,6 +206,7 @@ m_gline_la_SOURCES = m_gline.c
 m_globops_la_SOURCES = m_globops.c
 m_hash_la_SOURCES = m_hash.c
 m_help_la_SOURCES = m_help.c
+m_highlight_la_SOURCES = m_highlight.c
 m_info_la_SOURCES = m_info.c
 m_invite_la_SOURCES = m_invite.c
 m_ison_la_SOURCES = m_ison.c
diff --git a/modules/m_highlight.c b/modules/m_highlight.c
new file mode 100644 (file)
index 0000000..9dec7b4
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
+ *
+ *  Copyright (c) 2017 plexus development team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
+ *  USA
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "irc_string.h"
+#include "numeric.h"
+#include "modules.h"
+#include "memory.h"
+#include "hook.h"
+#include "channel_mode.h"
+#include "hash.h"
+#include "s_misc.h"
+#include "send.h"
+#include "conf.h"
+
+/* Per token, longest chain we will search */
+#define MAX_SEARCH_LEN 75
+
+static int
+is_masshl(struct Channel *chptr, const char *message)
+{
+  char msg[IRCD_BUFSIZE];
+  char *start = msg;
+  int hits = 0;
+
+  strlcpy(msg, message, sizeof(msg));
+
+  while (start < msg + sizeof(msg))
+  {
+    // Skip non nick
+    while (*start && !IsNickChar(*start))
+      ++start;
+
+    // Go to end of nick
+    char *end = start;
+    while (*end && IsNickChar(*end))
+      ++end;
+
+    const char *token = start;
+
+    *end = 0; // null end of token
+    start = end + 1; // proceed to next
+
+    struct Client *target = hash_find_client(token);
+
+    if (target == NULL || !IsClient(target))
+      continue;
+
+    // find_channel_link is O(n) over either target->channel or chptr->members - whichever is shorter
+    // don't bother with this client if it is >= MAX_SEARCH_LEN
+    int len = IRCD_MIN(dlink_list_length(&target->channel), dlink_list_length(&chptr->members));
+    if (len >= MAX_SEARCH_LEN)
+      continue;
+
+    struct Membership *ms = find_channel_link(target, chptr);
+    if (ms == NULL)
+      continue;
+
+    ++hits;
+
+    if (hits >= ConfigFileEntry.mass_highlight_nicks)
+      break;
+  }
+
+  return hits;
+}
+
+static void
+highlight_can_send(struct can_send_data *data)
+{
+  struct Client *client = data->client;
+  struct Channel *chptr = data->chptr;
+  struct Membership *ms = data->membership;
+  const char *message   = data->message;
+
+  if (!MyClient(client) || ConfigFileEntry.mass_highlight_nicks == 0)
+    return;
+
+  if (HasUMode(client, UMODE_OPER) || IsExemptLimits(client))
+    return;
+
+  // allow through non member messages because otherwise highlight blocker would be an
+  // information leak on who is on the channel
+  if (!ms || (ms->flags & (CHFL_OWNER | CHFL_PROTECTED | CHFL_CHANOP | CHFL_HALFOP | CHFL_VOICE)))
+    return;
+
+  int hits = is_masshl(chptr, message);
+  if (hits < ConfigFileEntry.mass_highlight_nicks)
+    return;
+
+  sendto_snomask(SNO_BOTS, L_ALL | SNO_ROUTE, "Blocked mass highlight from %s to channel %s",
+                get_client_name(client, HIDE_IP), chptr->chname);
+
+  data->ret = CAN_SEND_NO;
+}
+
+static struct Event can_send_event =
+{
+  .event = &can_send_hook,
+  .handler = highlight_can_send
+};
+
+static void
+module_init(void)
+{
+  hook_add(&can_send_event);
+}
+
+static void
+module_exit(void)
+{
+  hook_del(&can_send_event);
+}
+
+struct module module_entry =
+{
+  .version = "$Revision$",
+  .modinit = module_init,
+  .modexit = module_exit,
+};
index f55a30a30d3daf956913cea9516f3c81ac3a368a..05025ffdedd7433c4a904d6f17df2e574060c726 100644 (file)
@@ -1306,6 +1306,7 @@ set_default_conf(void)
   ConfigFileEntry.enable_extbans = 0;
   ConfigFileEntry.enable_forwarding = 0;
   ConfigFileEntry.message_digest_algorithm = EVP_sha1();
+  ConfigFileEntry.mass_highlight_nicks = 0;
 }
 
 static void
index c59cec463ae00a097681d90a161f797249a520f9..f34d0b0034c6fdf763816b306bc1d2e2f7c4ff50 100644 (file)
@@ -255,6 +255,7 @@ locops                      { return T_LOCOPS; }
 log                         { return T_LOG; }
 mask                        { return MASK; }
 masked                      { return TMASKED; }
+mass_highlight_nicks        { return MASS_HIGHLIGHT_NICKS; }
 match                       { return MATCH; }
 max_accept                  { return MAX_ACCEPT; }
 max_bans                    { return MAX_BANS; }
index dad0fe855824e8566173583d59b933ab7fa28114..948528e0f55db0a28280a463d6d3b5aaf65cd181 100644 (file)
@@ -401,6 +401,7 @@ reset_block_state(void)
 %token  THROTTLE_TIME
 %token  TKLINE_EXPIRE_NOTICES
 %token  TMASKED
+%token  MASS_HIGHLIGHT_NICKS
 %token  TS_MAX_DELTA
 %token  TS_WARN_DELTA
 %token  TWODOTS
@@ -3020,6 +3021,7 @@ general_item:       general_hide_spoof_ips | general_ignore_bogus_ts |
                     general_cloak_key |
                     general_account_whois | general_disable_chmodes | general_use_target_change |
                     general_enable_extbans | general_enable_forwarding | general_ssl_message_digest_algorithm |
+                    general_mass_highlight_nicks |
                    error;
 
 
@@ -3324,6 +3326,11 @@ general_ssl_message_digest_algorithm: SSL_MESSAGE_DIGEST_ALGORITHM '=' QSTRING '
   }
 };
 
+general_mass_highlight_nicks: MASS_HIGHLIGHT_NICKS '=' NUMBER ';'
+{
+  ConfigFileEntry.mass_highlight_nicks = $3;
+};
+
 umode_oitems:    umode_oitems ',' umode_oitem | umode_oitem;
 umode_oitem: T_NOCTCP
 {