From f4041a13c3894e282fb34010f3373d1950136a8c Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Mon, 7 Jan 2019 22:41:54 +0000 Subject: Release v3.0.0 release candidate 1. --- include/modules.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/modules.h b/include/modules.h index b4f13c6b7..b8c860fbc 100644 --- a/include/modules.h +++ b/include/modules.h @@ -99,7 +99,8 @@ struct ModResult { /** InspIRCd major version. * 1.2 -> 102; 2.1 -> 201; 2.12 -> 212 */ -#define INSPIRCD_VERSION_MAJ 202 +#define INSPIRCD_VERSION_MAJ 300 + /** InspIRCd API version. * If you change any API elements, increment this value. This counter should be * reset whenever the major version is changed. Modules can use these two values -- cgit v1.3.1-10-gc9f91 From f2e3fd5952b23209b084bde4f464e6643c8a00ff Mon Sep 17 00:00:00 2001 From: Matt Schatz Date: Tue, 8 Jan 2019 03:03:53 -0700 Subject: Improve X-line text consistency. - Change any "-Line", ":Line", or "*line" to "-line" throughout the X-line code, comments, and documentation. - Add periods to the end of some notices. - Correct a typo in the Q-line code comments. - Update the filter module documentation (shun addition). Co-authored-by: Robby --- docs/conf/filter.conf.example | 20 ++++++++++------ docs/conf/helpop-full.conf.example | 42 ++++++++++++++++----------------- docs/conf/helpop.conf.example | 4 ++-- docs/conf/inspircd.conf.example | 14 +++++------ docs/conf/modules.conf.example | 26 ++++++++++---------- include/bancache.h | 2 +- include/configreader.h | 4 ++-- include/inspircd.h | 2 +- include/users.h | 8 +++---- include/xline.h | 24 +++++++++---------- src/coremods/core_xline/cmd_eline.cpp | 8 +++---- src/coremods/core_xline/cmd_gline.cpp | 10 ++++---- src/coremods/core_xline/cmd_kline.cpp | 10 ++++---- src/coremods/core_xline/cmd_qline.cpp | 8 +++---- src/coremods/core_xline/cmd_zline.cpp | 8 +++---- src/coremods/core_xline/core_xline.cpp | 6 ++--- src/coremods/core_xline/core_xline.h | 10 ++++---- src/modules/m_cban.cpp | 4 ++-- src/modules/m_clearchan.cpp | 2 +- src/modules/m_connectban.cpp | 4 ++-- src/modules/m_dnsbl.cpp | 6 ++--- src/modules/m_filter.cpp | 10 ++++---- src/modules/m_rline.cpp | 18 +++++++------- src/modules/m_shun.cpp | 4 ++-- src/modules/m_spanningtree/treesocket.h | 2 +- src/modules/m_svshold.cpp | 6 ++--- src/snomasks.cpp | 4 ++-- src/usermanager.cpp | 2 +- src/xline.cpp | 12 +++++----- 29 files changed, 143 insertions(+), 137 deletions(-) (limited to 'include') diff --git a/docs/conf/filter.conf.example b/docs/conf/filter.conf.example index 26c68d2c3..29e1f530c 100644 --- a/docs/conf/filter.conf.example +++ b/docs/conf/filter.conf.example @@ -6,7 +6,7 @@ # reason="reason for filtering" # action="action to take" # flags="filter flags" -# duration="optional length of gline"> +# duration="optional duration of the G-line, Z-line or shun"> # # Valid actions for 'action' are: # @@ -25,15 +25,21 @@ # kill This disconnects the user, with the 'reason' parameter as # the kill reason. # -# gline G-LINE the user for 'duration' length of time. Durations may +# gline G-line the user for 'duration' length of time. Durations may # be specified using the notation 1y2d3h4m6s in a similar way to -# other glines, omitting the duration or setting it to 0 makes -# any glines set by this filter be permanent. +# other G-lines, omitting the duration or setting it to 0 makes +# any G-lines set by this filter be permanent. # -# zline Z-LINE the user for 'duration' length of time. Durations may +# zline Z-line the user for 'duration' length of time. Durations may # be specified using the notation 1y2d3h4m6s in a similar way to -# other zlines, omitting the duration or setting it to 0 makes -# any zlines set by this filter be permanent. +# other Z-lines, omitting the duration or setting it to 0 makes +# any Z-lines set by this filter be permanent. +# +# shun Shun the user for 'duration' length of time. Durations may +# be specified using the notation 1y2d3h4m6s in a similar way to +# other X-lines, omitting the duration or setting it to 0 makes +# any shuns set by this filter be permanent. +# Requires the shun module to be loaded. # # You can add filters from IRC using the /FILTER command. If you do this, they # will be set globally to your entire network. diff --git a/docs/conf/helpop-full.conf.example b/docs/conf/helpop-full.conf.example index 6834ca7c8..dec0e23d1 100644 --- a/docs/conf/helpop-full.conf.example +++ b/docs/conf/helpop-full.conf.example @@ -475,8 +475,8 @@ numeric lists)"> This command will add a filter when more than one parameter is given, for messages of the types specified by the flags, with the given -filter definition, action, duration (when the action is 'gline' or 'shun'), -and reason. +filter definition, action, duration (when the action is 'gline', +'zline' or 'shun'), and reason. The filter will take effect when a message of any type specified by the flags and matching the definition is sent to the server, and @@ -492,8 +492,8 @@ Block Blocks message and informs +s IRCops of the blocked message and all relevant info Silent Blocks message, but does not notify IRCops Kill Kills the user -Gline Glines the user for the specified duration -Zline Zlines the user for the specified duration +Gline G-lines the user for the specified duration +Zline Z-lines the user for the specified duration Shun Shuns the user for the specified duration (requires the shun module) Valid FILTER Flags @@ -513,8 +513,8 @@ The reason for the filter will be used as the reason for the action, unless the action is 'none', and is sent to the user when their text is blocked by 'block' and 'silent' actions. -A gline duration may be specified in seconds, or in the format -1y2w3d4h5m6s - meaning one year, two weeks, three days, 4 hours, 5 +A G-line, Z-line or shun duration may be specified in seconds, or in the +format 1y2w3d4h5m6s - meaning one year, two weeks, three days, 4 hours, 5 minutes and 6 seconds. All fields in this format are optional. When only one parameter is provided (the filter pattern) the provided @@ -721,7 +721,7 @@ Unloads and reloads a module on all linked servers."> +be negated by an E-line on *@, bans on *@ can be negated by +E-lines on *@, or *@, and bans on @* or @ +can be negated by any E-line that matches."> @@ -1070,8 +1070,8 @@ Note that all /STATS use is broadcast to online IRC operators."> R Allows receipt of remote oper commands (requires the operlog module). t Allows receipt of attempts to use /STATS (local and remote). v Allows receipt of oper-override notices (requires the override module). - x Allows receipt of local Xline notices (g/Z/q/k/e/R/shuns). - X Allows receipt of remote Xline notices (g/Z/q/k/e/R/shuns)."> + x Allows receipt of local X-line notices (G/Z/Q/K/E/R/SHUN/CBan). + X Allows receipt of remote X-line notices (G/Z/Q/K/E/R/SHUN/CBan)."> ###################### # EXTBANS # diff --git a/docs/conf/helpop.conf.example b/docs/conf/helpop.conf.example index 5285a4b6c..a4bfc751b 100644 --- a/docs/conf/helpop.conf.example +++ b/docs/conf/helpop.conf.example @@ -257,8 +257,8 @@ help channel if you have any questions."> R Allows receipt of remote oper commands (requires the operlog module). t Allows receipt of attempts to use /STATS (local and remote). v Allows receipt of oper-override notices (requires the override module). - x Allows receipt of local Xline notices (g/Z/q/k/e/R/shuns). - X Allows receipt of remote Xline notices (g/Z/q/k/e/R/shuns)."> + x Allows receipt of local X-line notices (G/Z/Q/K/E/R/SHUN/CBan). + X Allows receipt of remote X-line notices (G/Z/Q/K/E/R/SHUN/CBan)."> -# exception: Hosts that are exempt from [kgz]lines. +# exception: Hosts that are exempt from [KGZ]-lines. #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# -# Clear chan module: Allows opers to masskick, masskill or mass-G/ZLine -# all users on a channel using /CLEARCHAN. +# Clear chan module: Allows opers to masskick, masskill or +# mass G/Z-line all users on a channel using /CLEARCHAN. # #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# @@ -619,7 +619,7 @@ #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# # Connectban: Provides IP connection throttling. Any IP range that -# connects too many times (configurable) in an hour is Z-Lined for a +# connects too many times (configurable) in an hour is Z-lined for a # (configurable) duration, and their count resets to 0. # # @@ -1621,7 +1621,7 @@ #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# # Regular expression provider for glob or wildcard (?/*) matching. -# You must have at least 1 provider loaded to use the filter or rline +# You must have at least 1 provider loaded to use the filter or R-line # modules. This module has no additional requirements, as it uses the # matching already present in InspIRCd core. # @@ -1630,7 +1630,7 @@ # Regular expression provider for PCRE (Perl-Compatible Regular # Expressions). You need libpcre installed to compile and load this # module. You must have at least 1 provider loaded to use the filter or -# rline modules. +# R-line modules. # #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# @@ -1643,7 +1643,7 @@ # Regular expression provider for POSIX regular expressions. # You shouldn't need any additional libraries on a POSIX-compatible # system (i.e.: any Linux, BSD, but not Windows). You must have at -# least 1 provider loaded to use filter or rline. +# least 1 provider loaded to use the filter or R-line modules. # On POSIX-compliant systems, regex syntax can be found by using the # command: 'man 7 regex'. # @@ -1723,7 +1723,7 @@ # #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# -# R-Line module: Ban users through regular expression patterns. +# R-line module: Ban users through regular expression patterns. # # #-#-#-#-#-#-#-#-#-#-#-#- RLINE CONFIGURATION -#-#-#-#-#-#-#-#-#-#-#-#-# @@ -1732,15 +1732,15 @@ # useful under some situations, but *can* also use CPU with more users # on a server) then set 'matchonnickchange' to yes. # Also, this is where you set what Regular Expression engine is to be -# used. If you ever change it while running, all of your R-Lines will -# be wiped. This is the regex engine used by all R-Lines set, and +# used. If you ever change it while running, all of your R-lines will +# be wiped. This is the regex engine used by all R-lines set, and # regex_ must be loaded, or rline will be non-functional # until you load it or change the engine to one that is loaded. # # # -# Generally, you will NOT want to use 'glob' here, as this turns -# rline into just another gline. The exceptions are that rline will +# Generally, you will NOT want to use 'glob' here, as this turns an +# R-line into just another G-line. The exceptions are that R-lines will # always use the full "nick!user@host realname" string, rather than only # user@host, but beware that only the ? and * wildcards are available, # and are the only way to specify where the space can occur if you do @@ -2089,7 +2089,7 @@ # #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# -# SVSHold module: Implements SVSHOLD. Like Q:Lines, but can only be # +# SVSHold module: Implements SVSHOLD. Like Q-lines, but can only be # # added/removed by Services. # # # SVSHOLD does not generate server notices by default, you can turn @@ -2185,7 +2185,7 @@ # #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# -# XLine database: Stores all *Lines (G/Z/K/R/any added by other modules) +# XLine database: Stores all *-lines (G/Z/K/R/any added by other modules) # in a file which is re-loaded on restart. This is useful # for two reasons: it keeps bans so users may not evade them, and on # bigger networks, server connections will take less time as there will diff --git a/include/bancache.h b/include/bancache.h index 6e19e1ebe..e0c84ab54 100644 --- a/include/bancache.h +++ b/include/bancache.h @@ -62,7 +62,7 @@ class CoreExport BanCacheManager * @param ip The IP the item is for. * @param type The type of ban cache item. std::string. .empty() means it's a negative match (user is allowed freely). * @param reason The reason for the ban. Left .empty() if it's a negative match. - * @param seconds Number of seconds before nuking the bancache entry, the default is a day. This might seem long, but entries will be removed as glines/etc expire. + * @param seconds Number of seconds before nuking the bancache entry, the default is a day. This might seem long, but entries will be removed as G-lines/etc expire. */ BanCacheHit *AddHit(const std::string &ip, const std::string &type, const std::string &reason, time_t seconds = 0); BanCacheHit *GetHit(const std::string &ip); diff --git a/include/configreader.h b/include/configreader.h index 4360b8661..fd9401c0f 100644 --- a/include/configreader.h +++ b/include/configreader.h @@ -379,8 +379,8 @@ class CoreExport ServerConfig /** The number of seconds that the server clock can skip by before server operators are warned. */ time_t TimeSkipWarn; - /** True if we're going to hide ban reasons for non-opers (e.g. G-Lines, - * K-Lines, Z-Lines) + /** True if we're going to hide ban reasons for non-opers (e.g. G-lines, + * K-lines, Z-lines) */ bool HideBans; diff --git a/include/inspircd.h b/include/inspircd.h index 8ca2314eb..f5c7dbafb 100644 --- a/include/inspircd.h +++ b/include/inspircd.h @@ -284,7 +284,7 @@ class CoreExport InspIRCd */ TimerManager Timers; - /** X-Line manager. Handles G/K/Q/E line setting, removal and matching + /** X-line manager. Handles G/K/Q/E-line setting, removal and matching */ XLineManager* XLines; diff --git a/include/users.h b/include/users.h index ef19adb5d..469c17124 100644 --- a/include/users.h +++ b/include/users.h @@ -784,7 +784,7 @@ class CoreExport LocalUser : public User, public insp::intrusive_list_nodeWriteNotice("*** Target not found"); + user->WriteNotice("*** Target not found."); return CMD_FAILURE; } @@ -61,7 +61,7 @@ CmdResult CommandEline::Handle(User* user, const Params& parameters) unsigned long duration; if (!InspIRCd::Duration(parameters[1], duration)) { - user->WriteNotice("*** Invalid duration for E-line"); + user->WriteNotice("*** Invalid duration for E-line."); return CMD_FAILURE; } ELine* el = new ELine(ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), ih.first.c_str(), ih.second.c_str()); @@ -82,7 +82,7 @@ CmdResult CommandEline::Handle(User* user, const Params& parameters) else { delete el; - user->WriteNotice("*** E-Line for " + target + " already exists"); + user->WriteNotice("*** E-line for " + target + " already exists."); } } else @@ -93,7 +93,7 @@ CmdResult CommandEline::Handle(User* user, const Params& parameters) } else { - user->WriteNotice("*** E-Line " + target + " not found in list, try /stats e"); + user->WriteNotice("*** E-line " + target + " not found in list, try /stats e."); } } diff --git a/src/coremods/core_xline/cmd_gline.cpp b/src/coremods/core_xline/cmd_gline.cpp index a9de707c4..60dcd714a 100644 --- a/src/coremods/core_xline/cmd_gline.cpp +++ b/src/coremods/core_xline/cmd_gline.cpp @@ -50,7 +50,7 @@ CmdResult CommandGline::Handle(User* user, const Params& parameters) if (ih.first.empty()) { - user->WriteNotice("*** Target not found"); + user->WriteNotice("*** Target not found."); return CMD_FAILURE; } @@ -60,14 +60,14 @@ CmdResult CommandGline::Handle(User* user, const Params& parameters) else if (target.find('!') != std::string::npos) { - user->WriteNotice("*** G-Line cannot operate on nick!user@host masks"); + user->WriteNotice("*** G-line cannot operate on nick!user@host masks."); return CMD_FAILURE; } unsigned long duration; if (!InspIRCd::Duration(parameters[1], duration)) { - user->WriteNotice("*** Invalid duration for G-line"); + user->WriteNotice("*** Invalid duration for G-line."); return CMD_FAILURE; } GLine* gl = new GLine(ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), ih.first.c_str(), ih.second.c_str()); @@ -90,7 +90,7 @@ CmdResult CommandGline::Handle(User* user, const Params& parameters) else { delete gl; - user->WriteNotice("** G-Line for " + target + " already exists"); + user->WriteNotice("** G-line for " + target + " already exists."); } } @@ -102,7 +102,7 @@ CmdResult CommandGline::Handle(User* user, const Params& parameters) } else { - user->WriteNotice("*** G-Line " + target + " not found in list, try /stats g."); + user->WriteNotice("*** G-line " + target + " not found in list, try /stats g."); } } diff --git a/src/coremods/core_xline/cmd_kline.cpp b/src/coremods/core_xline/cmd_kline.cpp index 9b474d16c..813b9afa6 100644 --- a/src/coremods/core_xline/cmd_kline.cpp +++ b/src/coremods/core_xline/cmd_kline.cpp @@ -50,7 +50,7 @@ CmdResult CommandKline::Handle(User* user, const Params& parameters) if (ih.first.empty()) { - user->WriteNotice("*** Target not found"); + user->WriteNotice("*** Target not found."); return CMD_FAILURE; } @@ -60,14 +60,14 @@ CmdResult CommandKline::Handle(User* user, const Params& parameters) if (target.find('!') != std::string::npos) { - user->WriteNotice("*** K-Line cannot operate on nick!user@host masks"); + user->WriteNotice("*** K-line cannot operate on nick!user@host masks."); return CMD_FAILURE; } unsigned long duration; if (!InspIRCd::Duration(parameters[1], duration)) { - user->WriteNotice("*** Invalid duration for K-line"); + user->WriteNotice("*** Invalid duration for K-line."); return CMD_FAILURE; } KLine* kl = new KLine(ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), ih.first.c_str(), ih.second.c_str()); @@ -90,7 +90,7 @@ CmdResult CommandKline::Handle(User* user, const Params& parameters) else { delete kl; - user->WriteNotice("*** K-Line for " + target + " already exists"); + user->WriteNotice("*** K-line for " + target + " already exists."); } } else @@ -101,7 +101,7 @@ CmdResult CommandKline::Handle(User* user, const Params& parameters) } else { - user->WriteNotice("*** K-Line " + target + " not found in list, try /stats k."); + user->WriteNotice("*** K-line " + target + " not found in list, try /stats k."); } } diff --git a/src/coremods/core_xline/cmd_qline.cpp b/src/coremods/core_xline/cmd_qline.cpp index 893c8d213..086d860fc 100644 --- a/src/coremods/core_xline/cmd_qline.cpp +++ b/src/coremods/core_xline/cmd_qline.cpp @@ -40,14 +40,14 @@ CmdResult CommandQline::Handle(User* user, const Params& parameters) if (parameters[0].find('@') != std::string::npos || parameters[0].find('!') != std::string::npos || parameters[0].find('.') != std::string::npos) { - user->WriteNotice("*** A Q-Line only bans a nick pattern, not a nick!user@host pattern."); + user->WriteNotice("*** A Q-line only bans a nick pattern, not a nick!user@host pattern."); return CMD_FAILURE; } unsigned long duration; if (!InspIRCd::Duration(parameters[1], duration)) { - user->WriteNotice("*** Invalid duration for Q-line"); + user->WriteNotice("*** Invalid duration for Q-line."); return CMD_FAILURE; } QLine* ql = new QLine(ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), parameters[0].c_str()); @@ -69,7 +69,7 @@ CmdResult CommandQline::Handle(User* user, const Params& parameters) else { delete ql; - user->WriteNotice("*** Q-Line for " + parameters[0] + " already exists"); + user->WriteNotice("*** Q-line for " + parameters[0] + " already exists."); } } else @@ -80,7 +80,7 @@ CmdResult CommandQline::Handle(User* user, const Params& parameters) } else { - user->WriteNotice("*** Q-Line " + parameters[0] + " not found in list, try /stats q."); + user->WriteNotice("*** Q-line " + parameters[0] + " not found in list, try /stats q."); return CMD_FAILURE; } } diff --git a/src/coremods/core_xline/cmd_zline.cpp b/src/coremods/core_xline/cmd_zline.cpp index e81fc727f..31030adce 100644 --- a/src/coremods/core_xline/cmd_zline.cpp +++ b/src/coremods/core_xline/cmd_zline.cpp @@ -38,7 +38,7 @@ CmdResult CommandZline::Handle(User* user, const Params& parameters) { if (target.find('!') != std::string::npos) { - user->WriteNotice("*** You cannot include a nickname in a zline, a zline must ban only an IP mask"); + user->WriteNotice("*** You cannot include a nickname in a Z-line, a Z-line must ban only an IP mask."); return CMD_FAILURE; } @@ -65,7 +65,7 @@ CmdResult CommandZline::Handle(User* user, const Params& parameters) unsigned long duration; if (!InspIRCd::Duration(parameters[1], duration)) { - user->WriteNotice("*** Invalid duration for Z-line"); + user->WriteNotice("*** Invalid duration for Z-line."); return CMD_FAILURE; } ZLine* zl = new ZLine(ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), ipaddr); @@ -87,7 +87,7 @@ CmdResult CommandZline::Handle(User* user, const Params& parameters) else { delete zl; - user->WriteNotice("*** Z-Line for " + std::string(ipaddr) + " already exists"); + user->WriteNotice("*** Z-line for " + std::string(ipaddr) + " already exists."); } } else @@ -98,7 +98,7 @@ CmdResult CommandZline::Handle(User* user, const Params& parameters) } else { - user->WriteNotice("*** Z-Line " + target + " not found in list, try /stats Z."); + user->WriteNotice("*** Z-line " + target + " not found in list, try /stats Z."); return CMD_FAILURE; } } diff --git a/src/coremods/core_xline/core_xline.cpp b/src/coremods/core_xline/core_xline.cpp index ab80ab4ed..aa19bad34 100644 --- a/src/coremods/core_xline/core_xline.cpp +++ b/src/coremods/core_xline/core_xline.cpp @@ -66,16 +66,16 @@ class CoreModXLine : public Module ModResult OnUserPreNick(LocalUser* user, const std::string& newnick) CXX11_OVERRIDE { - // Check Q-Lines (for local nick changes only, remote servers have our Q-Lines to enforce themselves) + // Check Q-lines (for local nick changes only, remote servers have our Q-lines to enforce themselves) XLine* xline = ServerInstance->XLines->MatchesLine("Q", newnick); if (!xline) return MOD_RES_PASSTHRU; // No match - // A Q-Line matched the new nick, tell opers if the user is registered + // A Q-line matched the new nick, tell opers if the user is registered if (user->registered == REG_ALL) { - ServerInstance->SNO->WriteGlobalSno('a', "Q-Lined nickname %s from %s: %s", + ServerInstance->SNO->WriteGlobalSno('a', "Q-lined nickname %s from %s: %s", newnick.c_str(), user->GetFullRealHost().c_str(), xline->reason.c_str()); } diff --git a/src/coremods/core_xline/core_xline.h b/src/coremods/core_xline/core_xline.h index 1e0bc74cc..c607797f1 100644 --- a/src/coremods/core_xline/core_xline.h +++ b/src/coremods/core_xline/core_xline.h @@ -70,7 +70,7 @@ class InsaneBan class CommandEline : public Command { public: - /** Constructor for eline. + /** Constructor for E-line. */ CommandEline(Module* parent); @@ -87,7 +87,7 @@ class CommandEline : public Command class CommandGline : public Command { public: - /** Constructor for gline. + /** Constructor for G-line. */ CommandGline(Module* parent); @@ -104,7 +104,7 @@ class CommandGline : public Command class CommandKline : public Command { public: - /** Constructor for kline. + /** Constructor for K-line. */ CommandKline(Module* parent); @@ -127,7 +127,7 @@ class CommandQline : public Command }; public: - /** Constructor for qline. + /** Constructor for Q-line. */ CommandQline(Module* parent); @@ -150,7 +150,7 @@ class CommandZline : public Command }; public: - /** Constructor for zline. + /** Constructor for Z-line. */ CommandZline(Module* parent); diff --git a/src/modules/m_cban.cpp b/src/modules/m_cban.cpp index e0768aa88..3cdbbbdfb 100644 --- a/src/modules/m_cban.cpp +++ b/src/modules/m_cban.cpp @@ -114,7 +114,7 @@ class CommandCBan : public Command unsigned long duration; if (!InspIRCd::Duration(parameters[1], duration)) { - user->WriteNotice("*** Invalid duration for CBan"); + user->WriteNotice("*** Invalid duration for CBan."); return CMD_FAILURE; } const char *reason = (parameters.size() > 2) ? parameters[2].c_str() : "No reason supplied"; @@ -202,7 +202,7 @@ class ModuleCBan : public Module, public Stats::EventListener Version GetVersion() CXX11_OVERRIDE { - return Version("Gives /cban, aka C:lines. Think Q:lines, for channels.", VF_COMMON | VF_VENDOR); + return Version("Gives /cban, aka C-lines. Think Q-lines, for channels.", VF_COMMON | VF_VENDOR); } }; diff --git a/src/modules/m_clearchan.cpp b/src/modules/m_clearchan.cpp index 016d28737..dec49866c 100644 --- a/src/modules/m_clearchan.cpp +++ b/src/modules/m_clearchan.cpp @@ -211,7 +211,7 @@ class ModuleClearChan : public Module Version GetVersion() CXX11_OVERRIDE { - return Version("Adds /CLEARCHAN that allows opers to masskick, masskill or mass-G/ZLine users on a channel", VF_VENDOR|VF_OPTCOMMON); + return Version("Adds /CLEARCHAN that allows opers to masskick, masskill or mass G/Z-line users on a channel.", VF_VENDOR|VF_OPTCOMMON); } }; diff --git a/src/modules/m_connectban.cpp b/src/modules/m_connectban.cpp index d57ffca02..20121f5f9 100644 --- a/src/modules/m_connectban.cpp +++ b/src/modules/m_connectban.cpp @@ -73,7 +73,7 @@ class ModuleConnectBan : public Module if (i->second >= threshold) { - // Create zline for set duration. + // Create Z-line for set duration. ZLine* zl = new ZLine(ServerInstance->Time(), banduration, ServerInstance->Config->ServerName, banmessage, mask.str()); if (!ServerInstance->XLines->AddLine(zl, NULL)) { @@ -83,7 +83,7 @@ class ModuleConnectBan : public Module ServerInstance->XLines->ApplyLines(); std::string maskstr = mask.str(); std::string timestr = InspIRCd::TimeString(zl->expiry); - ServerInstance->SNO->WriteGlobalSno('x',"Module m_connectban added Z:line on *@%s to expire on %s: Connect flooding", + ServerInstance->SNO->WriteGlobalSno('x',"Module m_connectban added Z-line on %s to expire on %s: Connect flooding", maskstr.c_str(), timestr.c_str()); ServerInstance->SNO->WriteGlobalSno('a', "Connect flooding from IP range %s (%d)", maskstr.c_str(), threshold); connects.erase(i); diff --git a/src/modules/m_dnsbl.cpp b/src/modules/m_dnsbl.cpp index d1ca800b3..a645e2cd1 100644 --- a/src/modules/m_dnsbl.cpp +++ b/src/modules/m_dnsbl.cpp @@ -148,7 +148,7 @@ class DNSBLResolver : public DNS::Request if (ServerInstance->XLines->AddLine(kl,NULL)) { std::string timestr = InspIRCd::TimeString(kl->expiry); - ServerInstance->SNO->WriteGlobalSno('x',"K:line added due to DNSBL match on *@%s to expire on %s: %s", + ServerInstance->SNO->WriteGlobalSno('x', "K-line added due to DNSBL match on *@%s to expire on %s: %s", them->GetIPString().c_str(), timestr.c_str(), reason.c_str()); ServerInstance->XLines->ApplyLines(); } @@ -166,7 +166,7 @@ class DNSBLResolver : public DNS::Request if (ServerInstance->XLines->AddLine(gl,NULL)) { std::string timestr = InspIRCd::TimeString(gl->expiry); - ServerInstance->SNO->WriteGlobalSno('x',"G:line added due to DNSBL match on *@%s to expire on %s: %s", + ServerInstance->SNO->WriteGlobalSno('x', "G-line added due to DNSBL match on *@%s to expire on %s: %s", them->GetIPString().c_str(), timestr.c_str(), reason.c_str()); ServerInstance->XLines->ApplyLines(); } @@ -184,7 +184,7 @@ class DNSBLResolver : public DNS::Request if (ServerInstance->XLines->AddLine(zl,NULL)) { std::string timestr = InspIRCd::TimeString(zl->expiry); - ServerInstance->SNO->WriteGlobalSno('x',"Z:line added due to DNSBL match on %s to expire on %s: %s", + ServerInstance->SNO->WriteGlobalSno('x', "Z-line added due to DNSBL match on %s to expire on %s: %s", them->GetIPString().c_str(), timestr.c_str(), reason.c_str()); ServerInstance->XLines->ApplyLines(); } diff --git a/src/modules/m_filter.cpp b/src/modules/m_filter.cpp index 0c8b81e4b..849f99086 100644 --- a/src/modules/m_filter.cpp +++ b/src/modules/m_filter.cpp @@ -421,7 +421,7 @@ ModResult ModuleFilter::OnUserPreMessage(User* user, const MessageTarget& msgtar else if (f->action == FA_GLINE) { GLine* gl = new GLine(ServerInstance->Time(), f->duration, ServerInstance->Config->ServerName.c_str(), f->reason.c_str(), "*", user->GetIPString()); - ServerInstance->SNO->WriteGlobalSno('f', InspIRCd::Format("%s was glined because their message to %s matched %s (%s)", + ServerInstance->SNO->WriteGlobalSno('f', InspIRCd::Format("%s was G-lined because their message to %s matched %s (%s)", user->nick.c_str(), target.c_str(), f->freeform.c_str(), f->reason.c_str())); if (ServerInstance->XLines->AddLine(gl,NULL)) { @@ -433,7 +433,7 @@ ModResult ModuleFilter::OnUserPreMessage(User* user, const MessageTarget& msgtar else if (f->action == FA_ZLINE) { ZLine* zl = new ZLine(ServerInstance->Time(), f->duration, ServerInstance->Config->ServerName.c_str(), f->reason.c_str(), user->GetIPString()); - ServerInstance->SNO->WriteGlobalSno('f', InspIRCd::Format("%s was zlined because their message to %s matched %s (%s)", + ServerInstance->SNO->WriteGlobalSno('f', InspIRCd::Format("%s was Z-lined because their message to %s matched %s (%s)", user->nick.c_str(), target.c_str(), f->freeform.c_str(), f->reason.c_str())); if (ServerInstance->XLines->AddLine(zl,NULL)) { @@ -506,9 +506,9 @@ ModResult ModuleFilter::OnPreCommand(std::string& command, CommandBase::Params& } if (f->action == FA_GLINE) { - /* Note: We gline *@IP so that if their host doesnt resolve the gline still applies. */ + /* Note: We G-line *@IP so that if their host doesn't resolve the G-line still applies. */ GLine* gl = new GLine(ServerInstance->Time(), f->duration, ServerInstance->Config->ServerName.c_str(), f->reason.c_str(), "*", user->GetIPString()); - ServerInstance->SNO->WriteGlobalSno('f', InspIRCd::Format("%s was glined because their %s message matched %s (%s)", + ServerInstance->SNO->WriteGlobalSno('f', InspIRCd::Format("%s was G-lined because their %s message matched %s (%s)", user->nick.c_str(), command.c_str(), f->freeform.c_str(), f->reason.c_str())); if (ServerInstance->XLines->AddLine(gl,NULL)) @@ -521,7 +521,7 @@ ModResult ModuleFilter::OnPreCommand(std::string& command, CommandBase::Params& if (f->action == FA_ZLINE) { ZLine* zl = new ZLine(ServerInstance->Time(), f->duration, ServerInstance->Config->ServerName.c_str(), f->reason.c_str(), user->GetIPString()); - ServerInstance->SNO->WriteGlobalSno('f', InspIRCd::Format("%s was zlined because their %s message matched %s (%s)", + ServerInstance->SNO->WriteGlobalSno('f', InspIRCd::Format("%s was Z-lined because their %s message matched %s (%s)", user->nick.c_str(), command.c_str(), f->freeform.c_str(), f->reason.c_str())); if (ServerInstance->XLines->AddLine(zl,NULL)) diff --git a/src/modules/m_rline.cpp b/src/modules/m_rline.cpp index 77b3bc3aa..1247e81d3 100644 --- a/src/modules/m_rline.cpp +++ b/src/modules/m_rline.cpp @@ -32,7 +32,7 @@ class RLine : public XLine { public: - /** Create a R-Line. + /** Create a R-line. * @param s_time The set time * @param d The duration of the xline * @param src The sender of the xline @@ -81,7 +81,7 @@ class RLine : public XLine if (ServerInstance->XLines->AddLine(zl, NULL)) { std::string timestr = InspIRCd::TimeString(zl->expiry); - ServerInstance->SNO->WriteToSnoMask('x', "Z-line added due to R-line match on *@%s%s%s: %s", + ServerInstance->SNO->WriteToSnoMask('x', "Z-line added due to R-line match on %s%s%s: %s", zl->ipaddr.c_str(), zl->duration ? " to expire on " : "", zl->duration ? timestr.c_str() : "", zl->reason.c_str()); added_zline = true; } @@ -150,7 +150,7 @@ class CommandRLine : public Command unsigned long duration; if (!InspIRCd::Duration(parameters[1], duration)) { - user->WriteNotice("*** Invalid duration for R-line"); + user->WriteNotice("*** Invalid duration for R-line."); return CMD_FAILURE; } XLine *r = NULL; @@ -184,7 +184,7 @@ class CommandRLine : public Command else { delete r; - user->WriteNotice("*** R-Line for " + parameters[0] + " already exists"); + user->WriteNotice("*** R-line for " + parameters[0] + " already exists."); } } } @@ -196,7 +196,7 @@ class CommandRLine : public Command } else { - user->WriteNotice("*** R-Line " + parameters[0] + " not found in list, try /stats R."); + user->WriteNotice("*** R-line " + parameters[0] + " not found in list, try /stats R."); } } @@ -279,15 +279,15 @@ class ModuleRLine : public Module, public Stats::EventListener if (!rxfactory) { if (newrxengine.empty()) - ServerInstance->SNO->WriteToSnoMask('a', "WARNING: No regex engine loaded - R-Line functionality disabled until this is corrected."); + ServerInstance->SNO->WriteToSnoMask('a', "WARNING: No regex engine loaded - R-line functionality disabled until this is corrected."); else - ServerInstance->SNO->WriteToSnoMask('a', "WARNING: Regex engine '%s' is not loaded - R-Line functionality disabled until this is corrected.", newrxengine.c_str()); + ServerInstance->SNO->WriteToSnoMask('a', "WARNING: Regex engine '%s' is not loaded - R-line functionality disabled until this is corrected.", newrxengine.c_str()); ServerInstance->XLines->DelAll(f.GetType()); } else if ((!initing) && (rxfactory.operator->() != factory)) { - ServerInstance->SNO->WriteToSnoMask('a', "Regex engine has changed, removing all R-Lines"); + ServerInstance->SNO->WriteToSnoMask('a', "Regex engine has changed, removing all R-lines."); ServerInstance->XLines->DelAll(f.GetType()); } @@ -331,7 +331,7 @@ class ModuleRLine : public Module, public Stats::EventListener void OnUnloadModule(Module* mod) CXX11_OVERRIDE { - // If the regex engine became unavailable or has changed, remove all rlines + // If the regex engine became unavailable or has changed, remove all R-lines. if (!rxfactory) { ServerInstance->XLines->DelAll(f.GetType()); diff --git a/src/modules/m_shun.cpp b/src/modules/m_shun.cpp index e4fb2c11d..6453ace81 100644 --- a/src/modules/m_shun.cpp +++ b/src/modules/m_shun.cpp @@ -92,7 +92,7 @@ class CommandShun : public Command { if (!InspIRCd::Duration(parameters[1], duration)) { - user->WriteNotice("*** Invalid duration for SHUN"); + user->WriteNotice("*** Invalid duration for SHUN."); return CMD_FAILURE; } expr = parameters[2]; @@ -122,7 +122,7 @@ class CommandShun : public Command else { delete r; - user->WriteNotice("*** Shun for " + target + " already exists"); + user->WriteNotice("*** Shun for " + target + " already exists."); return CMD_FAILURE; } } diff --git a/src/modules/m_spanningtree/treesocket.h b/src/modules/m_spanningtree/treesocket.h index 878b34ad7..6206448c1 100644 --- a/src/modules/m_spanningtree/treesocket.h +++ b/src/modules/m_spanningtree/treesocket.h @@ -259,7 +259,7 @@ class TreeSocket : public BufferedSocket */ void SendFJoins(Channel* c); - /** Send G, Q, Z and E lines */ + /** Send G-, Q-, Z- and E-lines */ void SendXLines(); /** Send all known information about a channel */ diff --git a/src/modules/m_svshold.cpp b/src/modules/m_svshold.cpp index 52c250fef..0aaf113f0 100644 --- a/src/modules/m_svshold.cpp +++ b/src/modules/m_svshold.cpp @@ -76,7 +76,7 @@ class SVSHoldFactory : public XLineFactory public: SVSHoldFactory() : XLineFactory("SVSHOLD") { } - /** Generate a shun + /** Generate an SVSHOLD */ XLine* Generate(time_t set_time, unsigned long duration, const std::string& source, const std::string& reason, const std::string& xline_specific_mask) CXX11_OVERRIDE { @@ -130,7 +130,7 @@ class CommandSvshold : public Command unsigned long duration; if (!InspIRCd::Duration(parameters[1], duration)) { - user->WriteNotice("*** Invalid duration for SVSHOLD"); + user->WriteNotice("*** Invalid duration for SVSHOLD."); return CMD_FAILURE; } SVSHold* r = new SVSHold(ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), parameters[0].c_str()); @@ -221,7 +221,7 @@ class ModuleSVSHold : public Module, public Stats::EventListener Version GetVersion() CXX11_OVERRIDE { - return Version("Implements SVSHOLD. Like Q:Lines, but can only be added/removed by Services.", VF_COMMON | VF_VENDOR); + return Version("Implements SVSHOLD. Like Q-lines, but can only be added/removed by Services.", VF_COMMON | VF_VENDOR); } }; diff --git a/src/snomasks.cpp b/src/snomasks.cpp index 0b266ff7e..e39fb84fb 100644 --- a/src/snomasks.cpp +++ b/src/snomasks.cpp @@ -69,8 +69,8 @@ SnomaskManager::SnomaskManager() EnableSnomask('q',"QUIT"); /* Local quit notices */ EnableSnomask('k',"KILL"); /* Kill notices */ EnableSnomask('o',"OPER"); /* Oper up/down notices */ - EnableSnomask('a',"ANNOUNCEMENT"); /* formerly WriteOpers() - generic notices to all opers */ - EnableSnomask('x',"XLINE"); /* Xline notice (g/z/q/k/e) */ + EnableSnomask('a',"ANNOUNCEMENT"); /* formerly WriteOpers() - generic notices to all opers */ + EnableSnomask('x',"XLINE"); /* X-line notices (G/Z/Q/K/E/R/SHUN/CBan) */ EnableSnomask('t',"STATS"); /* Local or remote stats request */ } diff --git a/src/usermanager.cpp b/src/usermanager.cpp index 6f9d15502..a70a00085 100644 --- a/src/usermanager.cpp +++ b/src/usermanager.cpp @@ -132,7 +132,7 @@ void UserManager::AddUser(int socket, ListenSocket* via, irc::sockets::sockaddrs New->WriteNumeric(ERR_YOUREBANNEDCREEP, ServerInstance->Config->XLineMessage); if (ServerInstance->Config->HideBans) - this->QuitUser(New, b->Type + "-Lined", &b->Reason); + this->QuitUser(New, b->Type + "-lined", &b->Reason); else this->QuitUser(New, b->Reason); return; diff --git a/src/xline.cpp b/src/xline.cpp index 9c84101e1..55496b424 100644 --- a/src/xline.cpp +++ b/src/xline.cpp @@ -329,7 +329,7 @@ void ELine::Unset() ServerInstance->XLines->CheckELines(); } -// returns a pointer to the reason if a nickname matches a qline, NULL if it didnt match +// returns a pointer to the reason if a nickname matches a Q-line, NULL if it didn't match XLine* XLineManager::MatchesLine(const std::string &type, User* user) { @@ -523,13 +523,13 @@ bool XLine::IsBurstable() void XLine::DefaultApply(User* u, const std::string &line, bool bancache) { - const std::string banReason = line + "-Lined: " + reason; + const std::string banReason = line + "-lined: " + reason; if (!ServerInstance->Config->XLineMessage.empty()) u->WriteNumeric(ERR_YOUREBANNEDCREEP, ServerInstance->Config->XLineMessage); if (ServerInstance->Config->HideBans) - ServerInstance->Users->QuitUser(u, line + "-Lined", &banReason); + ServerInstance->Users->QuitUser(u, line + "-lined", &banReason); else ServerInstance->Users->QuitUser(u, banReason); @@ -629,7 +629,7 @@ bool QLine::Matches(User *u) void QLine::Apply(User* u) { - /* Force to uuid on apply of qline, no need to disconnect any more :) */ + /* Force to uuid on apply of Q-line, no need to disconnect anymore :) */ u->ChangeNick(u->uuid); } @@ -667,7 +667,7 @@ bool GLine::Matches(const std::string &str) void ELine::OnAdd() { - /* When adding one eline, only check the one eline */ + /* When adding one E-line, only check the one E-line */ const UserManager::LocalList& list = ServerInstance->Users.GetLocalUsers(); for (UserManager::LocalList::const_iterator u2 = list.begin(); u2 != list.end(); u2++) { @@ -681,7 +681,7 @@ void XLine::DisplayExpiry() { bool onechar = (type.length() == 1); ServerInstance->SNO->WriteToSnoMask('x', "Removing expired %s%s %s (set by %s %ld seconds ago): %s", - type.c_str(), (onechar ? "-Line" : ""), Displayable().c_str(), source.c_str(), (long)(ServerInstance->Time() - set_time), reason.c_str()); + type.c_str(), (onechar ? "-line" : ""), Displayable().c_str(), source.c_str(), (long)(ServerInstance->Time() - set_time), reason.c_str()); } const std::string& ELine::Displayable() -- cgit v1.3.1-10-gc9f91 From f400d5f394a258dee58fb56420acd65e22503761 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Mon, 14 Jan 2019 05:48:45 -0600 Subject: Redo OnSetEndPoint logic to fix duplicate clones (#1549). --- include/inspsocket.h | 3 ++- include/users.h | 10 +++++----- src/coremods/core_xline/core_xline.cpp | 9 +++++++++ src/inspsocket.cpp | 5 +++++ src/modules/m_cgiirc.cpp | 27 ++----------------------- src/modules/m_haproxy.cpp | 3 ++- src/users.cpp | 36 +++++++++++++++++++++------------- 7 files changed, 47 insertions(+), 46 deletions(-) (limited to 'include') diff --git a/include/inspsocket.h b/include/inspsocket.h index e432f9c16..69fdaac8b 100644 --- a/include/inspsocket.h +++ b/include/inspsocket.h @@ -312,8 +312,9 @@ class CoreExport StreamSocket : public EventHandler /** Called when the endpoint addresses are changed. * @param local The new local endpoint. * @param remote The new remote endpoint. + * @return true if the connection is still open, false if it has been closed */ - virtual void OnSetEndPoint(const irc::sockets::sockaddrs& local, const irc::sockets::sockaddrs& remote) { } + virtual bool OnSetEndPoint(const irc::sockets::sockaddrs& local, const irc::sockets::sockaddrs& remote); /** Send the given data out the socket, either now or when writes unblock */ diff --git a/include/users.h b/include/users.h index 469c17124..eaf400c67 100644 --- a/include/users.h +++ b/include/users.h @@ -380,9 +380,9 @@ class CoreExport User : public Extensible /** Sets the client IP for this user * @return true if the conversion was successful */ - virtual bool SetClientIP(const std::string& address, bool recheck_eline = true); + virtual bool SetClientIP(const std::string& address); - virtual void SetClientIP(const irc::sockets::sockaddrs& sa, bool recheck_eline = true); + virtual void SetClientIP(const irc::sockets::sockaddrs& sa); /** Constructor * @throw CoreException if the UID allocated to the user already exists @@ -689,7 +689,7 @@ class CoreExport UserIOHandler : public StreamSocket { } void OnDataReady() CXX11_OVERRIDE; - void OnSetEndPoint(const irc::sockets::sockaddrs& local, const irc::sockets::sockaddrs& remote) CXX11_OVERRIDE; + bool OnSetEndPoint(const irc::sockets::sockaddrs& local, const irc::sockets::sockaddrs& remote) CXX11_OVERRIDE; void OnError(BufferedSocketError error) CXX11_OVERRIDE; /** Adds to the user's write buffer. @@ -820,9 +820,9 @@ class CoreExport LocalUser : public User, public insp::intrusive_list_nodequitting) + return; + + user->exempt = (ServerInstance->XLines->MatchesLine("E", user) != NULL); + user->CheckLines(true); + } + ModResult OnUserPreNick(LocalUser* user, const std::string& newnick) CXX11_OVERRIDE { // Check Q-lines (for local nick changes only, remote servers have our Q-lines to enforce themselves) diff --git a/src/inspsocket.cpp b/src/inspsocket.cpp index 69c427212..ebbff448e 100644 --- a/src/inspsocket.cpp +++ b/src/inspsocket.cpp @@ -358,6 +358,11 @@ void StreamSocket::FlushSendQ(SendQueue& sq) } } +bool StreamSocket::OnSetEndPoint(const irc::sockets::sockaddrs& local, const irc::sockets::sockaddrs& remote) +{ + return false; +} + void StreamSocket::WriteData(const std::string &data) { if (fd < 0) diff --git a/src/modules/m_cgiirc.cpp b/src/modules/m_cgiirc.cpp index 4a5a4fb03..df8201bde 100644 --- a/src/modules/m_cgiirc.cpp +++ b/src/modules/m_cgiirc.cpp @@ -34,29 +34,6 @@ enum RPL_WHOISGATEWAY = 350 }; -// We need this method up here so that it can be accessed from anywhere -static void ChangeIP(LocalUser* user, const irc::sockets::sockaddrs& sa) -{ - // Set the users IP address and make sure they are in the right clone pool. - ServerInstance->Users->RemoveCloneCounts(user); - user->SetClientIP(sa); - ServerInstance->Users->AddClone(user); - if (user->quitting) - return; - - // Recheck the connect class. - user->MyClass = NULL; - user->SetClass(); - user->CheckClass(); - if (user->quitting) - return; - - // Check if this user matches any XLines. - user->CheckLines(true); - if (user->quitting) - return; -} - // Encapsulates information about an ident host. class IdentHost { @@ -215,7 +192,7 @@ class CommandWebIRC : public SplitCommand // Set the IP address sent via WEBIRC. We ignore the hostname and lookup // instead do our own DNS lookups because of unreliable gateways. - ChangeIP(user, ipaddr); + user->SetClientIP(ipaddr); return CMD_SUCCESS; } @@ -391,7 +368,7 @@ class ModuleCgiIRC user->uuid.c_str(), user->GetIPString().c_str(), address.addr().c_str(), user->ident.c_str(), newident.c_str()); user->ChangeIdent(newident); - ChangeIP(user, address); + user->SetClientIP(address); break; } return MOD_RES_PASSTHRU; diff --git a/src/modules/m_haproxy.cpp b/src/modules/m_haproxy.cpp index f61a39fdd..ee9079cbf 100644 --- a/src/modules/m_haproxy.cpp +++ b/src/modules/m_haproxy.cpp @@ -261,7 +261,8 @@ class HAProxyHook : public IOHookMiddle break; } - sock->OnSetEndPoint(server, client); + if (!sock->OnSetEndPoint(server, client)) + return -1; // Parse any available TLVs. while (tlv_index < address_length) diff --git a/src/users.cpp b/src/users.cpp index f11a7a380..a0b9c9d03 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -318,10 +318,11 @@ void UserIOHandler::AddWriteBuf(const std::string &data) WriteData(data); } -void UserIOHandler::OnSetEndPoint(const irc::sockets::sockaddrs& server, const irc::sockets::sockaddrs& client) +bool UserIOHandler::OnSetEndPoint(const irc::sockets::sockaddrs& server, const irc::sockets::sockaddrs& client) { memcpy(&user->server_sa, &server, sizeof(irc::sockets::sockaddrs)); user->SetClientIP(client); + return !user->quitting; } void UserIOHandler::OnError(BufferedSocketError) @@ -723,17 +724,17 @@ irc::sockets::cidr_mask User::GetCIDRMask() return irc::sockets::cidr_mask(client_sa, range); } -bool User::SetClientIP(const std::string& address, bool recheck_eline) +bool User::SetClientIP(const std::string& address) { irc::sockets::sockaddrs sa; if (!irc::sockets::aptosa(address, client_sa.port(), sa)) return false; - User::SetClientIP(sa, recheck_eline); + User::SetClientIP(sa); return true; } -void User::SetClientIP(const irc::sockets::sockaddrs& sa, bool recheck_eline) +void User::SetClientIP(const irc::sockets::sockaddrs& sa) { const std::string oldip(GetIPString()); memcpy(&client_sa, &sa, sizeof(irc::sockets::sockaddrs)); @@ -746,26 +747,33 @@ void User::SetClientIP(const irc::sockets::sockaddrs& sa, bool recheck_eline) ChangeDisplayedHost(GetIPString()); } -bool LocalUser::SetClientIP(const std::string& address, bool recheck_eline) +bool LocalUser::SetClientIP(const std::string& address) { irc::sockets::sockaddrs sa; if (!irc::sockets::aptosa(address, client_sa.port(), sa)) return false; - LocalUser::SetClientIP(sa, recheck_eline); + LocalUser::SetClientIP(sa); return true; } -void LocalUser::SetClientIP(const irc::sockets::sockaddrs& sa, bool recheck_eline) +void LocalUser::SetClientIP(const irc::sockets::sockaddrs& sa) { - if (sa != client_sa) - { - User::SetClientIP(sa); - if (recheck_eline) - this->exempt = (ServerInstance->XLines->MatchesLine("E", this) != NULL); + if (sa == client_sa) + return; - FOREACH_MOD(OnSetUserIP, (this)); - } + ServerInstance->Users->RemoveCloneCounts(this); + + User::SetClientIP(sa); + + FOREACH_MOD(OnSetUserIP, (this)); + + ServerInstance->Users->AddClone(this); + + // Recheck the connect class. + this->MyClass = NULL; + this->SetClass(); + this->CheckClass(); } void LocalUser::Write(const ClientProtocol::SerializedMessage& text) -- cgit v1.3.1-10-gc9f91 From 965c81baee0fb6f46aa788f45742d558f50c8b15 Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Tue, 22 Jan 2019 11:59:44 +0000 Subject: Rename OnClientProtocolProcessTag to OnProcessTag. --- include/clientprotocol.h | 2 +- src/clientprotocol.cpp | 2 +- src/modules/m_spanningtree/treesocket2.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/clientprotocol.h b/include/clientprotocol.h index 10b70e80b..ec033e166 100644 --- a/include/clientprotocol.h +++ b/include/clientprotocol.h @@ -549,7 +549,7 @@ class ClientProtocol::MessageTagProvider : public Events::ModuleEventListener * MOD_RES_PASSTHRU to make no decision. If no hooks accept a tag, the tag is rejected. * The default implementation returns MOD_RES_PASSTHRU. */ - virtual ModResult OnClientProtocolProcessTag(User* user, const std::string& tagname, std::string& tagvalue) + virtual ModResult OnProcessTag(User* user, const std::string& tagname, std::string& tagvalue) { return MOD_RES_PASSTHRU; } diff --git a/src/clientprotocol.cpp b/src/clientprotocol.cpp index a732855a5..212d65d6b 100644 --- a/src/clientprotocol.cpp +++ b/src/clientprotocol.cpp @@ -35,7 +35,7 @@ bool ClientProtocol::Serializer::HandleTag(LocalUser* user, const std::string& t for (::Events::ModuleEventProvider::SubscriberList::const_iterator i = list.begin(); i != list.end(); ++i) { MessageTagProvider* const tagprov = static_cast(*i); - const ModResult res = tagprov->OnClientProtocolProcessTag(user, tagname, tagvalue); + const ModResult res = tagprov->OnProcessTag(user, tagname, tagvalue); if (res == MOD_RES_ALLOW) return tags.insert(std::make_pair(tagname, MessageTagData(tagprov, tagvalue))).second; else if (res == MOD_RES_DENY) diff --git a/src/modules/m_spanningtree/treesocket2.cpp b/src/modules/m_spanningtree/treesocket2.cpp index dc24802fb..45f8a380f 100644 --- a/src/modules/m_spanningtree/treesocket2.cpp +++ b/src/modules/m_spanningtree/treesocket2.cpp @@ -292,7 +292,7 @@ void TreeSocket::ProcessTag(User* source, const std::string& tag, ClientProtocol for (Events::ModuleEventProvider::SubscriberList::const_iterator i = list.begin(); i != list.end(); ++i) { ClientProtocol::MessageTagProvider* const tagprov = static_cast(*i); - const ModResult res = tagprov->OnClientProtocolProcessTag(source, tagkey, tagval); + const ModResult res = tagprov->OnProcessTag(source, tagkey, tagval); if (res == MOD_RES_ALLOW) tags.insert(std::make_pair(tagkey, ClientProtocol::MessageTagData(tagprov, tagval))); else if (res == MOD_RES_DENY) -- cgit v1.3.1-10-gc9f91 From cbef0241a04eafe5250b75ebb3f7ef8c32ecb260 Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Wed, 23 Jan 2019 21:45:50 +0000 Subject: Implement support for the extended tag space for client tags. --- docs/conf/inspircd.conf.example | 6 +-- include/hashcomp.h | 5 ++- include/users.h | 3 ++ src/coremods/core_serialize_rfc.cpp | 75 +++++++++++++++++++++++++++---------- src/hashcomp.cpp | 4 +- src/users.cpp | 42 ++++++++++----------- 6 files changed, 86 insertions(+), 49 deletions(-) (limited to 'include') diff --git a/docs/conf/inspircd.conf.example b/docs/conf/inspircd.conf.example index f65f6f5de..f2db74500 100644 --- a/docs/conf/inspircd.conf.example +++ b/docs/conf/inspircd.conf.example @@ -367,11 +367,11 @@ # softsendq: amount of data in a client's send queue before the server # begins delaying their commands in order to allow the sendq to drain - softsendq="8192" + softsendq="10240" # recvq: amount of data allowed in a client's queue before they are dropped. - # Entering "8K" is equivalent to "8192", see above. - recvq="8K" + # Entering "10K" is equivalent to "10240", see above. + recvq="10K" # threshold: This specifies the amount of command penalty a user is allowed to have # before being quit or fakelagged due to flood. Normal commands have a penalty of 1, diff --git a/include/hashcomp.h b/include/hashcomp.h index f0e092729..80c02332d 100644 --- a/include/hashcomp.h +++ b/include/hashcomp.h @@ -197,7 +197,10 @@ namespace irc public: /** Create a tokenstream and fill it with the provided data. */ - tokenstream(const std::string& msg, size_t start = 0); + tokenstream(const std::string& msg, size_t start = 0, size_t end = std::string::npos); + + /** Retrieves the underlying message. */ + std::string& GetMessage() { return message; } /** Retrieve the next \ token in the token stream. * @param token The next token available, or an empty string if none remain. diff --git a/include/users.h b/include/users.h index eaf400c67..3937f74aa 100644 --- a/include/users.h +++ b/include/users.h @@ -681,10 +681,13 @@ class CoreExport User : public Extensible class CoreExport UserIOHandler : public StreamSocket { + private: + size_t checked_until; public: LocalUser* const user; UserIOHandler(LocalUser* me) : StreamSocket(StreamSocket::SS_USER) + , checked_until(0) , user(me) { } diff --git a/src/coremods/core_serialize_rfc.cpp b/src/coremods/core_serialize_rfc.cpp index 1ba330146..23a4c2052 100644 --- a/src/coremods/core_serialize_rfc.cpp +++ b/src/coremods/core_serialize_rfc.cpp @@ -19,11 +19,20 @@ #include "inspircd.h" +enum +{ + // From ircu. + ERR_INPUTTOOLONG = 417 +}; + class RFCSerializer : public ClientProtocol::Serializer { - /** Maximum size of the message tags portion of the message, including the `@` and the trailing space characters. - */ - static const std::string::size_type MAX_MESSAGE_TAG_LENGTH = 512; + + /** The maximum size of client-originated message tags in an incoming message including the `@`. */ + static const std::string::size_type MAX_CLIENT_MESSAGE_TAG_LENGTH = 4095; + + /** The maximum size of server-originated message tags in an outgoing message including the `@`. */ + static const std::string::size_type MAX_SERVER_MESSAGE_TAG_LENGTH = 511; static void SerializeTags(const ClientProtocol::TagMap& tags, const ClientProtocol::TagSelection& tagwl, std::string& line); @@ -47,15 +56,32 @@ bool RFCSerializer::Parse(LocalUser* user, const std::string& line, ClientProtoc return false; } - ServerInstance->Logs->Log("USERINPUT", LOG_RAWIO, "C[%s] I %s", user->uuid.c_str(), line.c_str()); + // Work out how long the message can actually be. + size_t maxline = ServerInstance->Config->Limits.MaxLine - start - 2; + if (line[start] == '@') + maxline += MAX_CLIENT_MESSAGE_TAG_LENGTH + 1; - irc::tokenstream tokens(line, start); - std::string token; + irc::tokenstream tokens(line, start, maxline); + ServerInstance->Logs->Log("USERINPUT", LOG_RAWIO, "C[%s] I %s", user->uuid.c_str(), tokens.GetMessage().c_str()); // This will always exist because of the check at the start of the function. + std::string token; tokens.GetMiddle(token); if (token[0] == '@') { + // Check that the client tags fit within the client tag space. + if (token.length() > MAX_CLIENT_MESSAGE_TAG_LENGTH) + { + user->WriteNumeric(ERR_INPUTTOOLONG, "Input line was too long"); + user->CommandFloodPenalty += 2000; + return false; + } + + // Truncate the RFC part of the message if it is too long. + size_t maxrfcline = token.length() + ServerInstance->Config->Limits.MaxLine - 1; + if (tokens.GetMessage().length() > maxrfcline) + tokens.GetMessage().erase(maxrfcline); + // Line begins with message tags, parse them. std::string tagval; irc::sepstream ss(token.substr(1), ';'); @@ -78,7 +104,6 @@ bool RFCSerializer::Parse(LocalUser* user, const std::string& line, ClientProtoc HandleTag(user, token, tagval, parseoutput.tags); } - // Try to read the prefix or command name. if (!tokens.GetMiddle(token)) { @@ -114,17 +139,29 @@ bool RFCSerializer::Parse(LocalUser* user, const std::string& line, ClientProtoc return true; } +namespace +{ + void CheckTagLength(std::string& line, size_t prevsize, size_t& length, size_t maxlength) + { + const std::string::size_type diffsize = line.size() - prevsize; + if (length + diffsize > maxlength) + line.erase(prevsize); + else + length += diffsize; + } +} + void RFCSerializer::SerializeTags(const ClientProtocol::TagMap& tags, const ClientProtocol::TagSelection& tagwl, std::string& line) { - char prefix = '@'; // First tag name is prefixed with a '@' + size_t client_tag_length = 0; + size_t server_tag_length = 0; for (ClientProtocol::TagMap::const_iterator i = tags.begin(); i != tags.end(); ++i) { if (!tagwl.IsSelected(tags, i)) continue; const std::string::size_type prevsize = line.size(); - line.push_back(prefix); - prefix = ';'; // Remaining tags are prefixed with ';' + line.push_back(prevsize ? ';' : '@'); line.append(i->first); const std::string& val = i->second.value; if (!val.empty()) @@ -133,16 +170,14 @@ void RFCSerializer::SerializeTags(const ClientProtocol::TagMap& tags, const Clie line.append(val); } - // The tags part of the message mustn't grow longer than what is allowed by the spec. If it does, - // remove last tag and stop adding more tags. - // - // One is subtracted from the limit before comparing because there must be a ' ' char after the last tag - // which also counts towards the limit. - if (line.size() > MAX_MESSAGE_TAG_LENGTH-1) - { - line.erase(prevsize); - break; - } + // The tags part of the message must not contain more client and server tags than allowed by the + // message tags specification. This is complicated by the tag space having separate limits for + // both server-originated and client-originated tags. If either of the tag limits is exceeded then + // the most recently added tag is removed. + if (i->first[0] == '+') + CheckTagLength(line, prevsize, client_tag_length, MAX_CLIENT_MESSAGE_TAG_LENGTH); + else + CheckTagLength(line, prevsize, server_tag_length, MAX_SERVER_MESSAGE_TAG_LENGTH); } if (!line.empty()) diff --git a/src/hashcomp.cpp b/src/hashcomp.cpp index 8febcbb5f..a51430a4b 100644 --- a/src/hashcomp.cpp +++ b/src/hashcomp.cpp @@ -193,8 +193,8 @@ size_t irc::insensitive::operator()(const std::string &s) const return t; } -irc::tokenstream::tokenstream(const std::string& msg, size_t start) - : message(msg, start) +irc::tokenstream::tokenstream(const std::string& msg, size_t start, size_t end) + : message(msg, start, end) , position(0) { } diff --git a/src/users.cpp b/src/users.cpp index eb87824fc..506cdf6d8 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -239,23 +239,30 @@ void UserIOHandler::OnDataReady() if (!user->HasPrivPermission("users/flood/no-fakelag")) penaltymax = user->MyClass->GetPenaltyThreshold() * 1000; - // The maximum size of an IRC message minus the terminating CR+LF. - const size_t maxmessage = ServerInstance->Config->Limits.MaxLine - 2; + // The cleaned message sent by the user or empty if not found yet. std::string line; - line.reserve(maxmessage); - bool eol_found; + // The position of the most \n character or npos if not found yet. + std::string::size_type eolpos; + + // The position within the recvq of the current character. std::string::size_type qpos; while (user->CommandFloodPenalty < penaltymax && getSendQSize() < sendqmax) { - qpos = 0; - eol_found = false; + // Check the newly received data for an EOL. + eolpos = recvq.find('\n', checked_until); + if (eolpos == std::string::npos) + { + checked_until = recvq.length(); + return; + } - const size_t qlen = recvq.length(); - while (qpos < qlen) + // We've found a line! Clean it up and move it to the line buffer. + line.reserve(eolpos); + for (qpos = 0; qpos < eolpos; ++qpos) { - char c = recvq[qpos++]; + char c = recvq[qpos]; switch (c) { case '\0': @@ -263,25 +270,14 @@ void UserIOHandler::OnDataReady() break; case '\r': continue; - case '\n': - eol_found = true; - break; } - if (eol_found) - break; - - if (line.length() < maxmessage) - line.push_back(c); + line.push_back(c); } - // if we return here, we haven't found a newline and make no modifications to recvq - // so we can wait for more data - if (!eol_found) - return; - // just found a newline. Terminate the string, and pull it out of recvq - recvq.erase(0, qpos); + recvq.erase(0, eolpos + 1); + checked_until = 0; // TODO should this be moved to when it was inserted in recvq? ServerInstance->stats.Recv += qpos; -- cgit v1.3.1-10-gc9f91 From 4047a143fc1d16350db70c94b9ea77d79de05714 Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Thu, 24 Jan 2019 15:10:02 +0000 Subject: Move the tag out of the core to a new module. --- docs/conf/inspircd.conf.example | 19 ---- docs/conf/modules.conf.example | 37 ++++++++ include/configreader.h | 15 ---- include/ctables.h | 21 ----- src/command_parse.cpp | 19 ---- src/configreader.cpp | 46 ---------- src/inspircd.cpp | 1 - src/mode.cpp | 11 --- src/modules/m_conn_umodes.cpp | 6 -- src/modules/m_disable.cpp | 189 ++++++++++++++++++++++++++++++++++++++++ src/modules/m_samode.cpp | 3 + 11 files changed, 229 insertions(+), 138 deletions(-) create mode 100644 src/modules/m_disable.cpp (limited to 'include') diff --git a/docs/conf/inspircd.conf.example b/docs/conf/inspircd.conf.example index f2db74500..890c9cc4c 100644 --- a/docs/conf/inspircd.conf.example +++ b/docs/conf/inspircd.conf.example @@ -520,25 +520,6 @@ # up to 100 entries. -#-#-#-#-#-#-#-#-#-#-#- DISABLED FEATURES -#-#-#-#-#-#-#-#-#-#-#-#-#-# -# # -# This tag is optional, and specifies one or more features which are # -# not available to non-operators. # -# # -# For example you may wish to disable NICK and prevent non-opers from # -# changing their nicknames. # -# Note that any disabled commands take effect only after the user has # -# 'registered' (e.g. after the initial USER/NICK/PASS on connection) # -# so for example disabling NICK will not cripple your network. # -# # -# You can also define if you want to disable any channelmodes # -# or usermodes from your users. # -# # -# `fakenonexistant' will make the ircd pretend that nonexistant # -# commands simply don't exist to non-opers ("no such command"). # -# # -# - #-#-#-#-#-#-#-#-#-#-#-#-#- SERVER OPTIONS -#-#-#-#-#-#-#-#-#-#-#-#-# # # # Settings to define which features are usable on your server. # diff --git a/docs/conf/modules.conf.example b/docs/conf/modules.conf.example index 0647f77c0..980d0d6a5 100644 --- a/docs/conf/modules.conf.example +++ b/docs/conf/modules.conf.example @@ -764,6 +764,43 @@ # # # Glob masks are accepted here also. # +#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# +# Disable module: Provides support for disabling commands and modes. # +# +# +#-#-#-#-#-#-#-#-#-#-#-#- DISABLE CONFIGURATION -#-#-#-#-#-#-#-#-#-#-#-# +# # +# If you have the disable module loaded then you need to specify the # +# commands and modes that you want disabled. Users who have not fully # +# connected yet are exempt from this module so you can e.g. disable # +# the NICK command but still allow users to connect to the server. # +# # +# commands - A space-delimited list of commands that can not be used # +# by users. You can exempt server operators from this with # +# the servers/use-disabled-commands privilege. # +# # +# chanmodes - One or more channel modes that can not be added/removed # +# by users. You can exempt server operators from this # +# with the servers/use-disabled-commands privilege. # +# # +# usermodes - One or more user modes that can not be added/removed by # +# users. You can exempt server operators from this with # +# the servers/use-disabled-commands privilege. # +# # +# fakenonexistent - Whether to pretend that a disabled command/mode # +# does not exist when executed/changed by a user. # +# Defaults to no. # +# # +# notifyopers - Whether to send a notice to snomask `a` when a user # +# is prevented from using a disabled command/mode. # +# Defaults to no. # +# # +# # + #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# # DNS blacklist module: Provides support for looking up IPs on one or # # more blacklists. # diff --git a/include/configreader.h b/include/configreader.h index fd9401c0f..511bedbee 100644 --- a/include/configreader.h +++ b/include/configreader.h @@ -332,18 +332,6 @@ class CoreExport ServerConfig */ std::string ServerDesc; - /** Pretend disabled commands don't exist. - */ - bool DisabledDontExist; - - /** This variable identifies which usermodes have been diabled. - */ - std::bitset<64> DisabledUModes; - - /** This variable identifies which chanmodes have been disabled. - */ - std::bitset<64> DisabledCModes; - /** How to treat a user in a channel who is banned. */ BannedUserTreatment RestrictBannedUsers; @@ -466,9 +454,6 @@ class CoreExport ServerConfig void Fill(); - /** Disables the commands specified in . */ - bool ApplyDisabledCommands(); - /** Escapes a value for storage in a configuration key. * @param str The string to escape. * @param xml Are we using the XML config format? diff --git a/include/ctables.h b/include/ctables.h index 8be40cc54..1c7d5b4bd 100644 --- a/include/ctables.h +++ b/include/ctables.h @@ -163,10 +163,6 @@ class CoreExport CommandBase : public ServiceProvider */ unsigned long use_count; - /** True if the command is disabled to non-opers - */ - bool disabled; - /** True if the command can be issued before registering */ bool works_before_reg; @@ -212,23 +208,6 @@ class CoreExport CommandBase : public ServiceProvider */ virtual void EncodeParameter(std::string& parameter, unsigned int index); - /** Disable or enable this command. - * @param setting True to disable the command. - */ - void Disable(bool setting) - { - disabled = setting; - } - - /** Obtain this command's disable state. - * @return true if the command is currently disabled - * (disabled commands can be used only by operators) - */ - bool IsDisabled() - { - return disabled; - } - /** @return true if the command works before registration. */ bool WorksBeforeReg() diff --git a/src/command_parse.cpp b/src/command_parse.cpp index c2ae39d49..7a732f8b5 100644 --- a/src/command_parse.cpp +++ b/src/command_parse.cpp @@ -266,24 +266,6 @@ void CommandParser::ProcessCommand(LocalUser* user, std::string& command, Comman } } - if ((user->registered == REG_ALL) && (!user->IsOper()) && (handler->IsDisabled())) - { - /* command is disabled! */ - user->CommandFloodPenalty += failpenalty; - if (ServerInstance->Config->DisabledDontExist) - { - user->WriteNumeric(ERR_UNKNOWNCOMMAND, command, "Unknown command"); - } - else - { - user->WriteNumeric(ERR_UNKNOWNCOMMAND, command, "This command has been disabled."); - } - - ServerInstance->SNO->WriteToSnoMask('a', "%s denied for %s (%s@%s)", - command.c_str(), user->nick.c_str(), user->ident.c_str(), user->GetRealHost().c_str()); - return; - } - if ((!command_p.empty()) && (command_p.back().empty()) && (!handler->allow_empty_last_param)) command_p.pop_back(); @@ -333,7 +315,6 @@ CommandBase::CommandBase(Module* mod, const std::string& cmd, unsigned int minpa , min_params(minpara) , max_params(maxpara) , use_count(0) - , disabled(false) , works_before_reg(false) , allow_empty_last_param(true) , Penalty(1) diff --git a/src/configreader.cpp b/src/configreader.cpp index ce03f1d9e..5a0ceff06 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -72,31 +72,6 @@ ServerConfig::~ServerConfig() delete EmptyTag; } -bool ServerConfig::ApplyDisabledCommands() -{ - // Enable everything first. - const CommandParser::CommandMap& commands = ServerInstance->Parser.GetCommands(); - for (CommandParser::CommandMap::const_iterator x = commands.begin(); x != commands.end(); ++x) - x->second->Disable(false); - - // Now disable the commands specified in the config. - std::string command; - irc::spacesepstream commandlist(ConfValue("disabled")->getString("commands")); - while (commandlist.GetToken(command)) - { - Command* handler = ServerInstance->Parser.GetHandler(command); - if (!handler) - { - ServerInstance->Logs->Log("CONFIG", LOG_DEBUG, "Unable to disable the %s command as it does not exist!", command.c_str()); - continue; - } - - ServerInstance->Logs->Log("CONFIG", LOG_DEBUG, "The %s command has been disabled", command.c_str()); - handler->Disable(true); - } - return true; -} - static void ReadXLine(ServerConfig* conf, const std::string& tag, const std::string& key, XLineFactory* make) { ConfigTagList tags = conf->ConfTags(tag); @@ -378,7 +353,6 @@ void ServerConfig::Fill() ServerDesc = server->getString("description", "Configure Me"); Network = server->getString("network", "Network"); NetBufferSize = ConfValue("performance")->getInt("netbuffersize", 10240, 1024, 65534); - DisabledDontExist = ConfValue("disabled")->getBool("fakenonexistant"); CustomVersion = security->getString("customversion"); HideBans = security->getBool("hidebans"); HideServer = security->getString("hideserver", security->getString("hidewhois")); @@ -429,25 +403,6 @@ void ServerConfig::Fill() RestrictBannedUsers = ServerConfig::BUT_RESTRICT_NOTIFY; else throw CoreException(restrictbannedusers + " is an invalid value, at " + options->getTagLocation()); - - DisabledUModes.reset(); - std::string modes = ConfValue("disabled")->getString("usermodes"); - for (std::string::const_iterator p = modes.begin(); p != modes.end(); ++p) - { - // Complain when the character is not a valid mode character. - if (!ModeParser::IsModeChar(*p)) - throw CoreException("Invalid usermode " + std::string(1, *p) + " was found."); - DisabledUModes.set(*p - 'A'); - } - - DisabledCModes.reset(); - modes = ConfValue("disabled")->getString("chanmodes"); - for (std::string::const_iterator p = modes.begin(); p != modes.end(); ++p) - { - if (!ModeParser::IsModeChar(*p)) - throw CoreException("Invalid chanmode " + std::string(1, *p) + " was found."); - DisabledCModes.set(*p - 'A'); - } } // WARNING: it is not safe to use most of the codebase in this function, as it @@ -723,7 +678,6 @@ void ConfigReaderThread::Finish() ServerInstance->Users.RehashCloneCounts(); ServerInstance->XLines->CheckELines(); ServerInstance->XLines->ApplyLines(); - Config->ApplyDisabledCommands(); User* user = ServerInstance->FindNick(TheUserUID); ConfigStatus status(user); diff --git a/src/inspircd.cpp b/src/inspircd.cpp index 7e299700b..09e48ea1f 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -442,7 +442,6 @@ InspIRCd::InspIRCd(int argc, char** argv) : // Build ISupport as ModuleManager::LoadAll() does not do it this->ISupport.Build(); - Config->ApplyDisabledCommands(); if (!pl.empty()) { diff --git a/src/mode.cpp b/src/mode.cpp index 5793b4e66..459eb21c8 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -312,17 +312,6 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, Mode } } - if (IS_LOCAL(user) && !user->IsOper()) - { - const std::bitset<64>& disabled = (type == MODETYPE_CHANNEL) ? ServerInstance->Config->DisabledCModes : ServerInstance->Config->DisabledUModes; - if (disabled.test(modechar - 'A')) - { - user->WriteNumeric(ERR_NOPRIVILEGES, InspIRCd::Format("Permission Denied - %s mode %c has been locked by the administrator", - type == MODETYPE_CHANNEL ? "channel" : "user", modechar)); - return MODEACTION_DENY; - } - } - if ((adding) && (IS_LOCAL(user)) && (mh->NeedsOper()) && (!user->HasModePermission(mh))) { /* It's an oper only mode, and they don't have access to it. */ diff --git a/src/modules/m_conn_umodes.cpp b/src/modules/m_conn_umodes.cpp index 1f2fe7455..3132aed40 100644 --- a/src/modules/m_conn_umodes.cpp +++ b/src/modules/m_conn_umodes.cpp @@ -38,10 +38,6 @@ class ModuleModesOnConnect : public Module void OnUserConnect(LocalUser* user) CXX11_OVERRIDE { - // Backup and zero out the disabled usermodes, so that we can override them here. - const std::bitset<64> save = ServerInstance->Config->DisabledUModes; - ServerInstance->Config->DisabledUModes.reset(); - ConfigTag* tag = user->MyClass->config; std::string ThisModes = tag->getString("modes"); if (!ThisModes.empty()) @@ -58,8 +54,6 @@ class ModuleModesOnConnect : public Module ServerInstance->Parser.CallHandler("MODE", modes, user); } - - ServerInstance->Config->DisabledUModes = save; } }; diff --git a/src/modules/m_disable.cpp b/src/modules/m_disable.cpp new file mode 100644 index 000000000..203f9ee64 --- /dev/null +++ b/src/modules/m_disable.cpp @@ -0,0 +1,189 @@ +/* + * InspIRCd -- Internet Relay Chat Daemon + * + * Copyright (C) 2019 Peter Powell + * + * This file is part of InspIRCd. InspIRCd 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, version 2. + * + * 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, see . + */ + + +#include "inspircd.h" + +enum +{ + // From ircu. + ERR_DISABLED = 517 +}; + +// Holds a list of disabled commands. +typedef std::vector CommandList; + +// Holds whether modes are disabled or not. +typedef std::bitset<64> ModeStatus; + +class ModuleDisable : public Module +{ + private: + CommandList commands; + ModeStatus chanmodes; + bool fakenonexistent; + bool notifyopers; + ModeStatus usermodes; + + void ReadModes(ConfigTag* tag, const std::string& field, ModeType type, ModeStatus& status) + { + const std::string modes = tag->getString(field); + for (std::string::const_iterator iter = modes.begin(); iter != modes.end(); ++iter) + { + const char& chr = *iter; + + // Check that the character is a valid mode letter. + if (!ModeParser::IsModeChar(chr)) + throw ModuleException(InspIRCd::Format("Invalid mode '%c' was specified in at %s", + chr, field.c_str(), tag->getTagLocation().c_str())); + + // Check that the mode actually exists. + ModeHandler* mh = ServerInstance->Modes->FindMode(chr, type); + if (!chr) + throw ModuleException(InspIRCd::Format("Non-existent mode '%c' was specified in at %s", + chr, field.c_str(), tag->getTagLocation().c_str())); + + // Disable the mode. + ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "The %c (%s) %s mode has been disabled", + mh->GetModeChar(), mh->name.c_str(), type == MODETYPE_CHANNEL ? "channel" : "user"); + status.set(chr - 'A'); + } + } + + void WriteLog(const char* message, ...) CUSTOM_PRINTF(2, 3) + { + std::string buffer; + VAFORMAT(buffer, message, message); + + if (notifyopers) + ServerInstance->SNO->WriteToSnoMask('a', buffer); + else + ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, buffer); + } + + public: + void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE + { + ConfigTag* tag = ServerInstance->Config->ConfValue("disabled"); + + // Parse the disabled commands. + CommandList newcommands; + irc::spacesepstream commandlist(tag->getString("commands")); + for (std::string command; commandlist.GetToken(command); ) + { + // Check that the command actually exists. + Command* handler = ServerInstance->Parser.GetHandler(command); + if (!handler) + throw ModuleException(InspIRCd::Format("Non-existent command '%s' was specified in at %s", + command.c_str(), tag->getTagLocation().c_str())); + + // Prevent admins from disabling COMMANDS and MODULES for transparency reasons. + if (handler->name == "COMMANDS" || handler->name == "MODULES") + continue; + + // Disable the command. + ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "The %s command has been disabled", handler->name.c_str()); + newcommands.push_back(handler->name); + } + + // Parse the disabled channel modes. + ModeStatus newchanmodes; + ReadModes(tag, "chanmodes", MODETYPE_CHANNEL, newchanmodes); + + // Parse the disabled user modes. + ModeStatus newusermodes; + ReadModes(tag, "usermodes", MODETYPE_USER, newusermodes); + + // The server config was valid so we can use these now. + chanmodes = newchanmodes; + usermodes = newusermodes; + commands.swap(newcommands); + + // Whether we should fake the non-existence of disabled things. + fakenonexistent = tag->getBool("fakenonexistent", tag->getBool("fakenonexistant")); + + // Whether to notify server operators via snomask `a` about the attempted use of disabled commands/modes. + notifyopers = tag->getBool("notifyopers"); + } + + ModResult OnPreCommand(std::string& command, CommandBase::Params& parameters, LocalUser* user, bool validated) CXX11_OVERRIDE + { + // If a command is unvalidated or the source is not registered we do nothing. + if (!validated || user->registered != REG_ALL) + return MOD_RES_PASSTHRU; + + // If the command is not disabled or the user has the servers/use-disabled-commands priv we do nothing. + if (!stdalgo::isin(commands, command) || user->HasPrivPermission("servers/use-disabled-commands")) + return MOD_RES_PASSTHRU; + + // The user has tried to execute a disabled command! + user->CommandFloodPenalty += 2000; + WriteLog("%s was blocked from executing the disabled %s command", user->GetFullRealHost().c_str(), command.c_str()); + + if (fakenonexistent) + { + // The server administrator has specified that disabled commands should be + // treated as if they do not exist. + user->WriteNumeric(ERR_UNKNOWNCOMMAND, command, "Unknown command"); + ServerInstance->stats.Unknown++; + return MOD_RES_DENY; + } + + // Inform the user that the command they executed has been disabled. + user->WriteNumeric(ERR_DISABLED, command, "Command disabled"); + return MOD_RES_DENY; + } + + ModResult OnRawMode(User* user, Channel* chan, ModeHandler* mh, const std::string& param, bool adding) CXX11_OVERRIDE + { + // If a mode change is remote or the source is not registered we do nothing. + if (!IS_LOCAL(user) || user->registered != REG_ALL) + return MOD_RES_PASSTHRU; + + // If the mode is not disabled or the user has the servers/use-disabled-modes priv we do nothing. + const std::bitset<64>& disabled = (mh->GetModeType() == MODETYPE_CHANNEL) ? chanmodes : usermodes; + if (!disabled.test(mh->GetModeChar() - 'A') || user->HasPrivPermission("servers/use-disabled-modes")) + return MOD_RES_PASSTHRU; + + // The user has tried to change a disabled mode! + const char* what = mh->GetModeType() == MODETYPE_CHANNEL ? "channel" : "user"; + WriteLog("%s was blocked from executing the disabled %s mode %c (%s)", + user->GetFullRealHost().c_str(), what, mh->GetModeChar(), mh->name.c_str()); + + if (fakenonexistent) + { + // The server administrator has specified that disabled modes should be + // treated as if they do not exist. + user->WriteNumeric(mh->GetModeType() == MODETYPE_CHANNEL ? ERR_UNKNOWNMODE : ERR_UNKNOWNSNOMASK, + mh->GetModeChar(), "is unknown mode char to me"); + return MOD_RES_DENY; + } + + // Inform the user that the mode they changed has been disabled. + user->WriteNumeric(ERR_NOPRIVILEGES, InspIRCd::Format("Permission Denied - %s mode %c (%s) is disabled", + what, mh->GetModeChar(), mh->name.c_str())); + return MOD_RES_DENY; + } + + Version GetVersion() CXX11_OVERRIDE + { + return Version("Provides support for disabling commands and modes", VF_VENDOR); + } +}; + +MODULE_INIT(ModuleDisable) diff --git a/src/modules/m_samode.cpp b/src/modules/m_samode.cpp index 8f28a7e9c..db3345b98 100644 --- a/src/modules/m_samode.cpp +++ b/src/modules/m_samode.cpp @@ -124,6 +124,9 @@ class ModuleSaMode : public Module void Prioritize() CXX11_OVERRIDE { + Module* disabled = ServerInstance->Modules->Find("m_disabled.so"); + ServerInstance->Modules->SetPriority(this, I_OnRawMode, PRIORITY_BEFORE, disabled); + Module *override = ServerInstance->Modules->Find("m_override.so"); ServerInstance->Modules->SetPriority(this, I_OnPreMode, PRIORITY_BEFORE, override); } -- cgit v1.3.1-10-gc9f91