Merge branch 'insp3' into master

This commit is contained in:
Sadie Powell 2019-01-24 15:58:57 +00:00
commit 1799bcff97
64 changed files with 616 additions and 451 deletions

View File

@ -20,8 +20,6 @@ If you encounter any bugs then [please file an issue](https://github.com/inspirc
## Installation
**The `master` branch contains the latest development version. If you are running a server then you probably want the `insp20` branch. You can obtain this from [the releases page](https://github.com/inspircd/inspircd/releases) or by running `git checkout $(git describe --abbrev=0 --tags insp20)` if you are installing via Git.**
Most InspIRCd users running a UNIX-like system build from source. A guide about how to do this is available on [the InspIRCd wiki](https://wiki.inspircd.org/Installation_From_Source).
Building from source on Windows is generally not recommended but [a guide is available](https://github.com/inspircd/inspircd/blob/master/win/README.txt) if you wish to do this.

2
configure vendored
View File

@ -244,7 +244,7 @@ affect the running of your server. It is recommended that you use a stable
version instead.
You can obtain the latest stable version from http://www.inspircd.org/ or by
running `<|GREEN git checkout $(git describe --abbrev=0 --tags insp20)|>` if you are
running `<|GREEN git checkout $(git describe --abbrev=0 --tags insp3)|>` if you are
installing from Git.
EOW
if (!prompt_bool $interactive, 'I understand this warning and want to continue anyway.', $opt_development // 0) {

View File

@ -1,12 +0,0 @@
# Configuration file for the censor module
# The tags for this module are formatted as follows:
#
# <badword text="simple word"
# replace="text to replace with">
#
# You can specify <badword text="simple word" replace="">
# to block lines containing the word
<badword text="shit" replace="poo">
<badword text="fuck" replace="(censored)">

View File

@ -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.

View File

@ -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.">
<helpop key="kline" value="/KLINE <user@host> [<duration> :<reason>]
Sets or removes a k-line (local host based ban) on a host and ident mask.
Sets or removes a K-line (local host based ban) on a host and ident mask.
You must specify all three parameters to add a ban, and one parameter
to remove a ban (just the user@host section).
@ -731,7 +731,7 @@ The duration may be specified in seconds, or in the format
<helpop key="zline" value="/ZLINE <ipmask> [<duration> :<reason>]
Sets or removes a z-line (ip based ban) on an ip range mask.
Sets or removes a Z-line (ip based ban) on an ip range mask.
You must specify all three parameters to add a ban, and one parameter
to remove a ban (just the ipmask).
@ -741,7 +741,7 @@ The duration may be specified in seconds, or in the format
<helpop key="qline" value="/QLINE <nickmask> [<duration> :<reason>]
Sets or removes a q-line (nick based ban) on a nick mask.
Sets or removes a Q-line (nick based ban) on a nick mask.
You must specify all three parameters to add a ban, and one parameter
to remove a ban (just the nickmask).
@ -751,7 +751,7 @@ The duration may be specified in seconds, or in the format
<helpop key="gline" value="/GLINE <user@host> [<duration> :<reason>]
Sets or removes a g-line (host based ban) on host mask.
Sets or removes a G-line (host based ban) on host mask.
You must specify all three parameters to add a ban, and one
parameter to remove a ban (just the user@host section).
@ -761,7 +761,7 @@ The duration may be specified in seconds, or in the format
<helpop key="eline" value="/ELINE <user@host> [<duration> :<reason>]
Sets or removes a e-line (global ban exception) on host mask.
Sets or removes a E-line (global ban exception) on host mask.
You must specify at least 3 parameters to add an exception, and one
parameter to remove an exception (just the user@host section).
@ -770,9 +770,9 @@ The duration may be specified in seconds, or in the format
5 minutes and 6 seconds. All fields in this format are optional.
This command has a few important limitations. Bans on *@<ip> can only
be negated by an eline on *@<ip>, bans on *@<host> can be negated by
elines on *@<ip>, or *@<host>, and bans on <ident>@* or <ident>@<host>
can be negated by any eline that matches.">
be negated by an E-line on *@<ip>, bans on *@<host> can be negated by
E-lines on *@<ip>, or *@<host>, and bans on <ident>@* or <ident>@<host>
can be negated by any E-line that matches.">
<helpop key="wallops" value="/WALLOPS <message>
@ -780,9 +780,9 @@ Sends a message to all +w users.">
<helpop key="rline" value="/RLINE <regex> [<duration> :<reason>]
Sets or removes an r-line (regex line) on a n!u@h\srealname mask. You
must specify all three parameters to add an rline, and one parameter
to remove an rline (just the regex).
Sets or removes an R-line (regex line) on a n!u@h\srealname mask. You
must specify all three parameters to add an R-line, and one parameter
to remove an R-line (just the regex).
The duration may be specified in seconds, or in the format
1y2w3d4h5m6s - meaning one year, two weeks, three days, 4 hours,
@ -794,11 +794,11 @@ Closes all unregistered connections to the local server.">
<helpop key="clearchan" value="/CLEARCHAN <channel> [<KILL|KICK|G|Z>] [<reason>]
Quits or kicks all non-opers from a channel, optionally G/Z-Lines them.
Quits or kicks all non-opers from a channel, optionally G/Z-lines them.
Useful for quickly nuking bot channels.
The default method, KILL, simply disconnects the victims from the server,
while methods G and Z also add G/Z-Lines for all the targets.
while methods G and Z also add G/Z-lines for all the targets.
When used, the victims won't see each other getting kicked or quitting.">
@ -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 #

View File

@ -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).">
<helpop key="extbans" value="Extended Bans
----------

View File

@ -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,
@ -520,25 +520,6 @@
# up to 100 entries.
<maxlist chan="*" limit="100">
#-#-#-#-#-#-#-#-#-#-#- 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"). #
# #
#<disabled commands="TOPIC MODE" usermodes="" chanmodes="" fakenonexistant="yes">
#-#-#-#-#-#-#-#-#-#-#-#-#- SERVER OPTIONS -#-#-#-#-#-#-#-#-#-#-#-#-#
# #
# Settings to define which features are usable on your server. #
@ -748,7 +729,7 @@
# when a remote whois (/WHOIS <nick> <nick>) is used.
#hideserver="*.example.com"
# hidebans: If this value is set to yes, when a user is banned ([gkz]lined)
# hidebans: If this value is set to yes, when a user is banned ([KGZ]-lined)
# only opers will see the ban message when the user is removed
# from the server.
hidebans="no"
@ -960,7 +941,7 @@
<badhost host="root@*" reason="Don't IRC as root!">
<badhost host="*@198.51.100.0/24" reason="This subnet is bad.">
# exception: Hosts that are exempt from [kgz]lines.
# exception: Hosts that are exempt from [KGZ]-lines.
<exception
# host: ident@hostname to exempt.
# Wildcards and CIDR (if you specify an IP) can be used.
@ -971,14 +952,14 @@
#-#-#-#-#-#-#-#-#-#-#- INSANE BAN OPTIONS -#-#-#-#-#-#-#-#-#-#-#-#-#-#
# #
# This optional tag allows you to specify how wide a gline, eline, #
# kline, zline or qline can be before it is forbidden from being #
# set. By setting hostmasks="yes", you can allow all G, K, E lines, #
# This optional tag allows you to specify how wide a G-line, E-line, #
# K-line, Z-line or Q-line can be before it is forbidden from being #
# set. By setting hostmasks="yes", you can allow all G-, K-, E-lines, #
# no matter how many users the ban would cover. This is not #
# recommended! By setting ipmasks="yes", you can allow all Z lines, #
# recommended! By setting ipmasks="yes", you can allow all Z-lines, #
# no matter how many users these cover too. Needless to say we #
# don't recommend you do this, or, set nickmasks="yes", which will #
# allow any qline. #
# allow any Q-line. #
# #
<insane

View File

@ -312,16 +312,21 @@
#<module name="cban">
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
# Censor module: Adds channel and user mode +G.
# Censor module: Adds channel and user mode +G which block phrases that
# are listed in the server bad words list.
#<module name="censor">
#
#-#-#-#-#-#-#-#-#-#-#- CENSOR CONFIGURATION -#-#-#-#-#-#-#-#-#-#-#-#
# #
# Optional - If you specify to use the censor module, then you must #
# specify some censor tags. See also: #
# https://wiki.inspircd.org/Modules/3.0/censor #
#
#<include file="examples/censor.conf.example">
# If you have the censor module loaded you should specify one or more #
# phrases to replace/block in user messages. The config for this is #
# formatted as follows: #
# #
# Replaces "eggplant" with "aubergine" within messages: #
# <badword text="eggplant" replace="aubergine"> #
# #
# Blocks messages that contain "fluffy capybaras": #
#<badword text="fluffy capybaras"> #
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
# CGI:IRC module: Enables forwarding the real IP address of a user from
@ -500,8 +505,8 @@
#<module name="classban">
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
# 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.
#<module name="clearchan">
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
@ -619,7 +624,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.
#<module name="connectban">
#
@ -764,6 +769,43 @@
#<goodchan name="#funtimes"> #
# Glob masks are accepted here also. #
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
# Disable module: Provides support for disabling commands and modes. #
#<module name="disable">
#
#-#-#-#-#-#-#-#-#-#-#-#- 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. #
# #
#<disabled commands="KICK TOPIC" #
# chanmodes="kp" #
# usermodes="iw" #
# fakenonexistent="yes" #
# notifyopers="no"> #
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
# DNS blacklist module: Provides support for looking up IPs on one or #
# more blacklists. #
@ -1021,7 +1063,6 @@
# the timeout for ident lookups here. If not defined, it will default #
# to 5 seconds. This is a non-blocking timeout which holds the user #
# in a 'connecting' state until the lookup is complete. #
# The bind value indicates which IP to bind outbound requests to. #
# nolookupprefix: If on, the idents of users being in a connect class #
# with ident lookups disabled (i.e. <connect useident="off">) will be #
# prefixed with a "~". If off, the ident of those users will not be #
@ -1621,7 +1662,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.
#<module name="regex_glob">
@ -1630,7 +1671,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.
#<module name="regex_pcre">
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
@ -1643,7 +1684,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'.
#<module name="regex_posix">
@ -1723,7 +1764,7 @@
#<module name="restrictmsg">
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
# R-Line module: Ban users through regular expression patterns.
# R-line module: Ban users through regular expression patterns.
#<module name="rline">
#
#-#-#-#-#-#-#-#-#-#-#-#- RLINE CONFIGURATION -#-#-#-#-#-#-#-#-#-#-#-#-#
@ -1732,15 +1773,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_<engine> must be loaded, or rline will be non-functional
# until you load it or change the engine to one that is loaded.
#
#<rline matchonnickchange="yes" engine="pcre">
#
# 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 +2130,7 @@
#<module name="starttls">
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
# 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. #
#<module name="svshold">
# SVSHOLD does not generate server notices by default, you can turn
@ -2185,7 +2226,7 @@
# <wsorigin allow="https://*.example.com/">
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
# 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

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
@ -379,8 +367,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;
@ -466,9 +454,6 @@ class CoreExport ServerConfig
void Fill();
/** Disables the commands specified in <disabled:commands>. */
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?

View File

@ -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()

View File

@ -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 \<middle> token in the token stream.
* @param token The next token available, or an empty string if none remain.

View File

@ -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;

View File

@ -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
*/

View File

@ -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

View File

@ -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
@ -681,15 +681,18 @@ 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)
{
}
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.
@ -784,7 +787,7 @@ class CoreExport LocalUser : public User, public insp::intrusive_list_node<Local
*/
unsigned int lastping:1;
/** This is true if the user matched an exception (E:Line). It is used to save time on ban checks.
/** This is true if the user matched an exception (E-line). It is used to save time on ban checks.
*/
unsigned int exempt:1;
@ -803,14 +806,14 @@ class CoreExport LocalUser : public User, public insp::intrusive_list_node<Local
already_sent_t already_sent;
/** Check if the user matches a G or K line, and disconnect them if they do.
* @param doZline True if ZLines should be checked (if IP has changed since initial connect)
/** Check if the user matches a G- or K-line, and disconnect them if they do.
* @param doZline True if Z-lines should be checked (if IP has changed since initial connect)
* Returns true if the user matched a ban, false else.
*/
bool CheckLines(bool doZline = false);
/** Use this method to fully connect a user.
* This will send the message of the day, check G/K/E lines, etc.
* This will send the message of the day, check G/K/E-lines, etc.
*/
void FullConnect();
@ -820,9 +823,9 @@ class CoreExport LocalUser : public User, public insp::intrusive_list_node<Local
*/
void SetClass(const std::string &explicit_name = "");
bool SetClientIP(const std::string& address, bool recheck_eline = true) CXX11_OVERRIDE;
bool SetClientIP(const std::string& address) CXX11_OVERRIDE;
void SetClientIP(const irc::sockets::sockaddrs& sa, bool recheck_eline = true) CXX11_OVERRIDE;
void SetClientIP(const irc::sockets::sockaddrs& sa) CXX11_OVERRIDE;
/** Send a NOTICE message from the local server to the user.
* The message will be sent even if the user is connected to a remote server.

View File

@ -22,7 +22,7 @@
#pragma once
/** XLine is the base class for ban lines such as G lines and K lines.
/** XLine is the base class for ban lines such as G-lines and K-lines.
* Modules may derive from this, and their xlines will automatically be
* handled as expected by any protocol modules (e.g. m_spanningtree will
* propogate them using AddLine). The process of translating a type+pattern
@ -67,7 +67,7 @@ class CoreExport XLine : public classbase
}
/** Change creation time of an xline. Updates expiry
* to be after the creation time
* to be after the creation time.
*/
virtual void SetCreateTime(time_t created)
{
@ -102,7 +102,7 @@ class CoreExport XLine : public classbase
virtual void Unset() { }
/** Called when the expiry message is to be displayed for the
* line. Usually a line in the form 'expiring Xline blah, set by...'
* line. Usually a line in the form 'expiring X-line blah, set by...'
* see the DisplayExpiry methods of GLine, ELine etc.
*/
virtual void DisplayExpiry();
@ -111,7 +111,7 @@ class CoreExport XLine : public classbase
* e.g. '*\@foo' or '*baz*'. This must always return the full pattern
* in a form which can be used to construct an entire derived xline,
* even if it is stored differently internally (e.g. GLine stores the
* ident and host parts seperately but will still return ident\@host
* ident and host parts separately but will still return ident\@host
* for its Displayable() method).
*/
virtual const std::string& Displayable() = 0;
@ -157,7 +157,7 @@ class CoreExport KLine : public XLine
{
public:
/** Create a K-Line.
/** Create a K-line.
* @param s_time The set time
* @param d The duration of the xline
* @param src The sender of the xline
@ -203,7 +203,7 @@ class CoreExport KLine : public XLine
class CoreExport GLine : public XLine
{
public:
/** Create a G-Line.
/** Create a G-line.
* @param s_time The set time
* @param d The duration of the xline
* @param src The sender of the xline
@ -247,7 +247,7 @@ class CoreExport GLine : public XLine
class CoreExport ELine : public XLine
{
public:
/** Create an E-Line.
/** Create an E-line.
* @param s_time The set time
* @param d The duration of the xline
* @param src The sender of the xline
@ -291,7 +291,7 @@ class CoreExport ELine : public XLine
class CoreExport ZLine : public XLine
{
public:
/** Create a Z-Line.
/** Create a Z-line.
* @param s_time The set time
* @param d The duration of the xline
* @param src The sender of the xline
@ -327,7 +327,7 @@ class CoreExport ZLine : public XLine
class CoreExport QLine : public XLine
{
public:
/** Create a G-Line.
/** Create a Q-line.
* @param s_time The set time
* @param d The duration of the xline
* @param src The sender of the xline
@ -399,7 +399,7 @@ class CoreExport XLineFactory
virtual ~XLineFactory() { }
};
/** XLineManager is a class used to manage glines, klines, elines, zlines and qlines,
/** XLineManager is a class used to manage G-lines, K-lines, E-lines, Z-lines and Q-lines,
* or any other line created by a module. It also manages XLineFactory classes which
* can generate a specialized XLine for use by another module.
*/
@ -436,7 +436,7 @@ class CoreExport XLineManager
*/
IdentHostPair IdentSplit(const std::string &ident_and_host);
/** Checks what users match e:lines and sets their ban exempt flag accordingly.
/** Checks what users match E-lines and sets their ban exempt flag accordingly.
*/
void CheckELines();
@ -476,7 +476,7 @@ class CoreExport XLineManager
/** Registers an xline factory.
* An xline factory is a class which when given a particular xline type,
* will generate a new XLine specialized to that type. For example if you
* pass the XLineFactory that handles glines some data it will return a
* pass the XLineFactory that handles G-lines some data it will return a
* pointer to a GLine, polymorphically represented as XLine. This is used where
* you do not know the full details of the item you wish to create, e.g. in a
* server protocol module like m_spanningtree, when you receive xlines from other

View File

@ -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<MessageTagProvider*>(*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)

View File

@ -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)

View File

@ -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 <options:restrictbannedusers> 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);

View File

@ -193,18 +193,14 @@ class ModuleHostnameLookup : public Module
void OnSetUserIP(LocalUser* user) CXX11_OVERRIDE
{
// If core_dns is not loaded or hostname resolution is disabled for the user's
// connect class then the logic in this function does not apply.
if (!DNS || !user->MyClass->resolvehostnames)
{
user->WriteNotice("*** Skipping host resolution (disabled by server administrator)");
return;
}
// Clients can't have a DNS hostname if they aren't connected via IPv4 or IPv6.
if (user->client_sa.family() != AF_INET && user->client_sa.family() != AF_INET6)
{
user->WriteNotice("*** Skipping host resolution (connected via a non-IP socket)");
return;
}
user->WriteNotice("*** Looking up your hostname...");

View File

@ -29,8 +29,12 @@ CommandVersion::CommandVersion(Module* parent)
CmdResult CommandVersion::Handle(User* user, const Params& parameters)
{
std::string version = ServerInstance->GetVersionString((user->IsOper()));
user->WriteNumeric(RPL_VERSION, version);
Numeric::Numeric numeric(RPL_VERSION);
irc::tokenstream tokens(ServerInstance->GetVersionString(user->IsOper()));
for (std::string token; tokens.GetTrailing(token); )
numeric.push(token);
user->WriteNumeric(numeric);
LocalUser *lu = IS_LOCAL(user);
if (lu != NULL)
{

View File

@ -95,12 +95,24 @@ class MessageCommandBase : public Command
ChanModeReference noextmsgmode;
/** Send a PRIVMSG or NOTICE message to all local users from the given user
* @param user User sending the message
* @param msg The message to send
* @param mt Type of the message (MSG_PRIVMSG or MSG_NOTICE)
* @param tags Message tags to include in the outgoing protocol message
* @param source The user sending the message.
* @param msg The details of the message to send.
*/
static void SendAll(User* user, const std::string& msg, MessageType mt, const ClientProtocol::TagMap& tags);
static void SendAll(User* source, const MessageDetails& details)
{
ClientProtocol::Messages::Privmsg message(ClientProtocol::Messages::Privmsg::nocopy, source, "$*", details.text, details.type);
message.AddTags(details.tags_out);
message.SetSideEffect(true);
ClientProtocol::Event messageevent(ServerInstance->GetRFCEvents().privmsg, message);
const UserManager::LocalList& list = ServerInstance->Users.GetLocalUsers();
for (UserManager::LocalList::const_iterator i = list.begin(); i != list.end(); ++i)
{
LocalUser* user = *i;
if ((user->registered == REG_ALL) && (!details.exemptions.count(user)))
user->Send(messageevent);
}
}
public:
MessageCommandBase(Module* parent, MessageType mt)
@ -128,21 +140,6 @@ class MessageCommandBase : public Command
}
};
void MessageCommandBase::SendAll(User* user, const std::string& msg, MessageType mt, const ClientProtocol::TagMap& tags)
{
ClientProtocol::Messages::Privmsg message(ClientProtocol::Messages::Privmsg::nocopy, user, "$*", msg, mt);
message.AddTags(tags);
message.SetSideEffect(true);
ClientProtocol::Event messageevent(ServerInstance->GetRFCEvents().privmsg, message);
const UserManager::LocalList& list = ServerInstance->Users.GetLocalUsers();
for (UserManager::LocalList::const_iterator i = list.begin(); i != list.end(); ++i)
{
if ((*i)->registered == REG_ALL)
(*i)->Send(messageevent);
}
}
CmdResult MessageCommandBase::HandleMessage(User* user, const Params& parameters, MessageType mt)
{
User *dest;
@ -171,7 +168,7 @@ CmdResult MessageCommandBase::HandleMessage(User* user, const Params& parameters
FOREACH_MOD(OnUserMessage, (user, msgtarget, msgdetails));
if (InspIRCd::Match(ServerInstance->Config->ServerName, servername, NULL))
{
SendAll(user, msgdetails.text, mt, msgdetails.tags_out);
SendAll(user, msgdetails);
}
FOREACH_MOD(OnUserPostMessage, (user, msgtarget, msgdetails));
return CMD_SUCCESS;

View File

@ -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())

View File

@ -50,7 +50,7 @@ CmdResult CommandEline::Handle(User* user, const Params& parameters)
if (ih.first.empty())
{
user->WriteNotice("*** 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.");
}
}

View File

@ -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.");
}
}

View File

@ -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.");
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -64,18 +64,27 @@ class CoreModXLine : public Module
{
}
void OnSetUserIP(LocalUser* user) CXX11_OVERRIDE
{
if (user->quitting)
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)
// 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());
}

View File

@ -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);

View File

@ -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)
{
}

View File

@ -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())
{

View File

@ -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)

View File

@ -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. */
@ -587,7 +576,8 @@ ModeHandler::Id ModeParser::AllocateModeId(ModeType mt)
void ModeParser::AddMode(ModeHandler* mh)
{
if (!ModeParser::IsModeChar(mh->GetModeChar()))
throw ModuleException("Invalid letter for mode " + mh->name);
throw ModuleException(InspIRCd::Format("Mode letter for %s is invalid: %c",
mh->name.c_str(), mh->GetModeChar()));
/* A mode prefix of ',' is not acceptable, it would fuck up server to server.
* A mode prefix of ':' will fuck up both server to server, and client to server.
@ -597,15 +587,19 @@ void ModeParser::AddMode(ModeHandler* mh)
if (pm)
{
if ((pm->GetPrefix() > 126) || (pm->GetPrefix() == ',') || (pm->GetPrefix() == ':') || (pm->GetPrefix() == '#'))
throw ModuleException("Invalid prefix for mode " + mh->name);
throw ModuleException(InspIRCd::Format("Mode prefix for %s is invalid: %c",
mh->name.c_str(), pm->GetPrefix()));
if (FindPrefix(pm->GetPrefix()))
throw ModuleException("Prefix already exists for mode " + mh->name);
PrefixMode* otherpm = FindPrefix(pm->GetPrefix());
if (otherpm)
throw ModuleException(InspIRCd::Format("Mode prefix for %s already by used by %s from %s: %c",
mh->name.c_str(), otherpm->name.c_str(), otherpm->creator->ModuleSourceFile.c_str(), pm->GetPrefix()));
}
ModeHandler*& slot = modehandlers[mh->GetModeType()][mh->GetModeChar()-65];
if (slot)
throw ModuleException("Letter is already in use for mode " + mh->name);
throw ModuleException(InspIRCd::Format("Mode letter for %s already by used by %s from %s: %c",
mh->name.c_str(), slot->name.c_str(), slot->creator->ModuleSourceFile.c_str(), mh->GetModeChar()));
// The mode needs an id if it is either a user mode, a simple mode (flag) or a parameter mode.
// Otherwise (for listmodes and prefix modes) the id remains MODEID_MAX, which is invalid.
@ -613,8 +607,13 @@ void ModeParser::AddMode(ModeHandler* mh)
if ((mh->GetModeType() == MODETYPE_USER) || (mh->IsParameterMode()) || (!mh->IsListMode()))
modeid = AllocateModeId(mh->GetModeType());
if (!modehandlersbyname[mh->GetModeType()].insert(std::make_pair(mh->name, mh)).second)
throw ModuleException("Mode name already in use: " + mh->name);
std::pair<ModeHandlerMap::iterator, bool> res = modehandlersbyname[mh->GetModeType()].insert(std::make_pair(mh->name, mh));
if (!res.second)
{
ModeHandler* othermh = res.first->second;
throw ModuleException(InspIRCd::Format("Mode name %s already used by %c from %s",
mh->name.c_str(), othermh->GetModeChar(), othermh->creator->ModuleSourceFile.c_str()));
}
// Everything is fine, add the mode

View File

@ -107,6 +107,7 @@ class ModuleAlias : public Module
ModuleAlias()
: botmode(this, "bot")
, active(false)
{
}

View File

@ -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);
}
};

View File

@ -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;

View File

@ -200,7 +200,7 @@ class CommandCheck : public Command
opcmdlist.Add(oper->AllowedOperCommands.ToString());
opcmdlist.Flush();
CheckContext::List privlist(context, "permissions");
opcmdlist.Add(oper->AllowedPrivs.ToString());
privlist.Add(oper->AllowedPrivs.ToString());
privlist.Flush();
}
}

View File

@ -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);
}
};

View File

@ -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;
}
};

View File

@ -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);

189
src/modules/m_disable.cpp Normal file
View File

@ -0,0 +1,189 @@
/*
* InspIRCd -- Internet Relay Chat Daemon
*
* Copyright (C) 2019 Peter Powell <petpow@saberuk.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "inspircd.h"
enum
{
// From ircu.
ERR_DISABLED = 517
};
// Holds a list of disabled commands.
typedef std::vector<std::string> 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 <disabled:%s> 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 <disabled:%s> 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 <disabled:commands> 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)

View File

@ -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();
}
@ -420,10 +420,14 @@ class ModuleDNSBL : public Module, public Stats::EventListener
std::string dnsbl;
if (!myclass->config->readString("dnsbl", dnsbl))
return MOD_RES_PASSTHRU;
std::string* match = nameExt.get(user);
std::string myname = match ? *match : "";
if (dnsbl == myname)
if (!match)
return MOD_RES_PASSTHRU;
if (InspIRCd::Match(*match, dnsbl))
return MOD_RES_PASSTHRU;
return MOD_RES_DENY;
}

View File

@ -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))

View File

@ -240,7 +240,7 @@ class HAProxyHook : public IOHookMiddle
{
case AF_INET:
memcpy(&client.in4.sin_addr.s_addr, &recvq[0], 4);
memcpy(&server.in4.sin_addr.s_addr, &recvq[4], 8);
memcpy(&server.in4.sin_addr.s_addr, &recvq[4], 4);
memcpy(&client.in4.sin_port, &recvq[8], 2);
memcpy(&server.in4.sin_port, &recvq[10], 2);
tlv_index = 12;
@ -256,12 +256,13 @@ class HAProxyHook : public IOHookMiddle
case AF_UNIX:
memcpy(client.un.sun_path, &recvq[0], 108);
memcpy(client.un.sun_path, &recvq[108], 108);
memcpy(server.un.sun_path, &recvq[108], 108);
tlv_index = 216;
break;
}
sock->OnSetEndPoint(server, client);
if (!sock->OnSetEndPoint(server, client))
return -1;
// Parse any available TLVs.
while (tlv_index < address_length)

View File

@ -47,7 +47,7 @@ class HostRule
std::string suffix;
public:
HostRule(const std::string& Host, const std::string& Mask, const insp::flat_set<int>& Ports)
HostRule(const std::string& Mask, const std::string& Host, const insp::flat_set<int>& Ports)
: action(HCA_SET)
, host(Host)
, mask(Mask)

View File

@ -275,12 +275,24 @@ class ModuleIdent : public Module
NoLookupPrefix = tag->getBool("nolookupprefix", false);
}
void OnUserInit(LocalUser *user) CXX11_OVERRIDE
void OnSetUserIP(LocalUser* user) CXX11_OVERRIDE
{
IdentRequestSocket* isock = ext.get(user);
if (isock)
{
// If an ident lookup request was in progress then cancel it.
isock->Close();
ext.unset(user);
}
// The ident protocol requires that clients are connecting over a protocol with ports.
if (user->client_sa.family() != AF_INET && user->client_sa.family() != AF_INET6)
return;
// We don't want to look this up once the user has connected.
if (user->registered == REG_ALL)
return;
ConfigTag* tag = user->MyClass->config;
if (!tag->getBool("useident", true))
return;
@ -289,7 +301,7 @@ class ModuleIdent : public Module
try
{
IdentRequestSocket *isock = new IdentRequestSocket(user);
isock = new IdentRequestSocket(user);
ext.set(user, isock);
}
catch (ModuleException &e)

View File

@ -40,25 +40,26 @@ class ModuleIRCv3EchoMessage : public Module
LocalUser* const localuser = static_cast<LocalUser*>(user);
const std::string& text = details.echo_original ? details.original_text : details.text;
const ClientProtocol::TagMap& tags = details.echo_original ? details.tags_in : details.tags_out;
if (target.type == MessageTarget::TYPE_USER)
{
User* destuser = target.Get<User>();
ClientProtocol::Messages::Privmsg privmsg(ClientProtocol::Messages::Privmsg::nocopy, user, destuser, text, details.type);
privmsg.AddTags(details.tags_in);
privmsg.AddTags(tags);
localuser->Send(ServerInstance->GetRFCEvents().privmsg, privmsg);
}
else if (target.type == MessageTarget::TYPE_CHANNEL)
{
Channel* chan = target.Get<Channel>();
ClientProtocol::Messages::Privmsg privmsg(ClientProtocol::Messages::Privmsg::nocopy, user, chan, text, details.type, target.status);
privmsg.AddTags(details.tags_in);
privmsg.AddTags(tags);
localuser->Send(ServerInstance->GetRFCEvents().privmsg, privmsg);
}
else
{
const std::string* servername = target.Get<std::string>();
ClientProtocol::Messages::Privmsg privmsg(ClientProtocol::Messages::Privmsg::nocopy, user, *servername, text, details.type);
privmsg.AddTags(details.tags_in);
privmsg.AddTags(tags);
localuser->Send(ServerInstance->GetRFCEvents().privmsg, privmsg);
}
}

View File

@ -18,6 +18,7 @@
#include "inspircd.h"
#include "modules/account.h"
class ModulePassForward : public Module
{
@ -82,6 +83,13 @@ class ModulePassForward : public Module
if (!user->MyClass->config->getString("password").empty())
return;
AccountExtItem* actext = GetAccountExtItem();
if (actext && actext->get(user))
{
// User is logged in already (probably via SASL) don't forward the password
return;
}
if (!nickrequired.empty())
{
/* Check if nick exists and its server is ulined */

View File

@ -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());

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -47,6 +47,6 @@ CmdResult CommandAway::HandleRemote(::RemoteUser* u, Params& params)
CommandAway::Builder::Builder(User* user)
: CmdBuilder(user, "AWAY")
{
if (user->awaymsg.empty())
if (!user->awaymsg.empty())
push_int(user->awaytime).push_last(user->awaymsg);
}

View File

@ -324,8 +324,12 @@ ModResult ModuleSpanningTree::HandleVersion(const CommandBase::Params& parameter
// If it's empty it might be that the server is still syncing (full version hasn't arrived yet)
// or the server is a 2.0 server and does not send a full version.
bool showfull = ((user->IsOper()) && (!found->GetFullVersion().empty()));
const std::string& Version = (showfull ? found->GetFullVersion() : found->GetVersion());
user->WriteNumeric(RPL_VERSION, Version);
Numeric::Numeric numeric(RPL_VERSION);
irc::tokenstream tokens(showfull ? found->GetFullVersion() : found->GetVersion());
for (std::string token; tokens.GetTrailing(token); )
numeric.push(token);
user->WriteNumeric(numeric);
}
else
{

View File

@ -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 */

View File

@ -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<ClientProtocol::MessageTagProvider*>(*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)

View File

@ -54,8 +54,7 @@ class SSLCertExt : public ExtensionItem
void unset(Extensible* container)
{
void* old = unset_raw(container);
delete static_cast<std::string*>(old);
free(container, unset_raw(container));
}
std::string serialize(SerializeFormat format, const Extensible* container, void* item) const CXX11_OVERRIDE

View File

@ -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);
}
};

View File

@ -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 */
}

View File

@ -76,6 +76,7 @@ void UserManager::AddUser(int socket, ListenSocket* via, irc::sockets::sockaddrs
this->clientlist[New->nick] = New;
this->AddClone(New);
this->local_users.push_front(New);
FOREACH_MOD(OnUserInit, (New));
if (!SocketEngine::AddFd(eh, FD_WANT_FAST_READ | FD_WANT_EDGE_WRITE))
{
@ -132,7 +133,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;
@ -162,8 +163,6 @@ void UserManager::AddUser(int socket, ListenSocket* via, irc::sockets::sockaddrs
FOREACH_MOD(OnSetUserIP, (New));
if (New->quitting)
return;
FOREACH_MOD(OnUserInit, (New));
}
void UserManager::QuitUser(User* user, const std::string& quitreason, const std::string* operreason)

View File

@ -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;
const size_t qlen = recvq.length();
while (qpos < qlen)
// Check the newly received data for an EOL.
eolpos = recvq.find('\n', checked_until);
if (eolpos == std::string::npos)
{
char c = recvq[qpos++];
checked_until = recvq.length();
return;
}
// 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];
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;
@ -318,10 +314,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 +720,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 +743,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)
@ -796,7 +800,11 @@ void LocalUser::Write(const ClientProtocol::SerializedMessage& text)
void LocalUser::Send(ClientProtocol::Event& protoev)
{
if (!serializer)
{
ServerInstance->Logs->Log("USERS", LOG_DEBUG, "BUG: LocalUser::Send() called on %s who does not have a serializer!",
GetFullRealHost().c_str());
return;
}
// In the most common case a static LocalUser field, sendmsglist, is passed to the event to be
// populated. The list is cleared before returning.

View File

@ -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()