Merge branch 'insp3' into master.

This commit is contained in:
Sadie Powell 2020-10-27 10:50:28 +00:00
commit 5a88a78f99
31 changed files with 473 additions and 130 deletions

View File

@ -18,6 +18,7 @@ jobs:
clang \
g++ \
git \
libargon2-dev \
libc++-dev \
libc++abi-dev \
libgnutls28-dev \
@ -35,7 +36,7 @@ jobs:
pkg-config
- name: Run configure
run: |
./configure --enable-extras "geo_maxmind ldap mysql pgsql regex_pcre regex_posix regex_re2 regex_tre sqlite3 ssl_gnutls ssl_mbedtls ssl_openssl sslrehashsignal"
./configure --enable-extras "argon2 geo_maxmind ldap mysql pgsql regex_pcre regex_posix regex_re2 regex_tre sqlite3 ssl_gnutls ssl_mbedtls ssl_openssl sslrehashsignal"
./configure --development --disable-auto-extras --socketengine ${{ matrix.socketengine }}
- name: Build core
run: |

View File

@ -13,8 +13,8 @@ jobs:
- uses: actions/checkout@v2
- name: Install dependencies
run: |
brew update
for PACKAGE in pkg-config gnutls libmaxminddb libpq mbedtls mysql-client openssl@1.1 pcre re2 sqlite tre;
brew update || true
for PACKAGE in pkg-config argon2 gnutls libmaxminddb libpq mbedtls mysql-client openssl@1.1 pcre re2 sqlite tre;
do
brew install $PACKAGE || brew upgrade $PACKAGE
done
@ -22,7 +22,7 @@ jobs:
brew link --force --overwrite mysql-client
- name: Run configure
run: |
./configure --enable-extras "geo_maxmind ldap mysql pgsql regex_pcre regex_posix regex_re2 regex_tre sqlite3 ssl_gnutls ssl_mbedtls ssl_openssl sslrehashsignal"
./configure --enable-extras "argon2 geo_maxmind ldap mysql pgsql regex_pcre regex_posix regex_re2 regex_tre sqlite3 ssl_gnutls ssl_mbedtls ssl_openssl sslrehashsignal"
./configure --development --disable-auto-extras --socketengine ${{ matrix.socketengine }}
- name: Build core
run: |

View File

@ -4,6 +4,7 @@ on:
- cron: '0 0 15 * *'
jobs:
build:
if: github.repository == 'inspircd/inspircd'
runs-on: ubuntu-latest
env:
REF_BRANCH: ${{ github.ref }}
@ -11,8 +12,8 @@ jobs:
- uses: actions/checkout@v2
- name : Set a couple env variables
run: |
echo "::set-env name=DATE::$(date +'%Y-%m-%d')"
echo "::set-env name=REF_BRANCH::${REF_BRANCH//refs\/heads\//}"
echo "DATE=$(date +'%Y-%m-%d')" >> $GITHUB_ENV
echo "REF_BRANCH=${REF_BRANCH//refs\/heads\//}" >> $GITHUB_ENV
- name: Whitelist some directories and files
run: |
echo "\

1
.gitignore vendored
View File

@ -15,6 +15,7 @@
/include/config.h
/src/modules/m_argon2.cpp
/src/modules/m_geo_maxmind.cpp
/src/modules/m_ldap.cpp
/src/modules/m_mysql.cpp

22
configure vendored
View File

@ -352,8 +352,8 @@ Would you like to enable extra modules manually?
EOQ
if (prompt_bool $interactive, $question, 0) {
foreach my $extra (<$RealDir/src/modules/extra/m_*.cpp>) {
my $module_name = basename $extra, '.cpp';
if (prompt_bool $interactive, "Would you like to enable $module_name?", 0) {
my $module_name = module_shrink $extra;
if (prompt_bool $interactive, "Would you like to enable the <|BOLD $module_name|> module?", 0) {
enable_extras $module_name;
}
}
@ -362,6 +362,7 @@ if (prompt_bool $interactive, $question, 0) {
# system './modulemanager', 'enable', '--auto';
my %modules = (
# Missing: m_ldap, m_regex_stdlib, m_ssl_mbedtls
'm_argon2.cpp' => 'pkg-config --exists libargon2',
'm_geo_maxmind.cpp' => 'pkg-config --exists libmaxminddb',
'm_mysql.cpp' => 'mysql_config --version',
'm_pgsql.cpp' => 'pg_config --version',
@ -438,8 +439,7 @@ Configuration is complete! You have chosen to build with the following settings:
EOM
for my $file (<$RealDir/src/modules/m_*>) {
my $module = basename $file, '.cpp';
say " * $module" if -l $file;
say " * ${\module_shrink $file}" if -l $file;
}
my @makeargs;
@ -487,7 +487,7 @@ sub list_extras () {
my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
closedir $dd;
undef $dd;
my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
my $maxlen = (sort { $b <=> $a } (map { length module_shrink $_ } (@extras)))[0];
my %extras = ();
EXTRA: for my $extra (@extras) {
next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
@ -555,9 +555,9 @@ EXTRA: for my $extra (@extras) {
for my $extra (sort {$a cmp $b} keys(%extras)) {
my $text = $extras{$extra};
if ($text =~ m/needed by/ && $text !~ m/enabled/) {
printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, module_shrink($extra), $text, ($text =~ m/needed by/ ? ")" : "");
} else {
printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
printf "%-*s = %s%s\n", $maxlen, module_shrink($extra), $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
}
}
return keys(%extras) if wantarray; # Can be used by manage_extras.
@ -568,8 +568,8 @@ sub enable_extras(@) {
my $extradir = catdir $moduledir, 'extra';
for my $extra (@_) {
my $shortname = $extra =~ s/(?:^m_|\.cpp$)//gr;
my $extrafile = "m_$shortname.cpp";
my $shortname = module_shrink $extra;
my $extrafile = module_expand $extra;
my $extrapath = catfile $extradir, $extrafile;
if (!-f $extrapath) {
@ -599,8 +599,8 @@ sub disable_extras(@) {
my $extradir = catdir $moduledir, 'extra';
for my $extra (@_) {
my $shortname = $extra =~ s/(?:^m_|\.cpp$)//gr;
my $extrafile = "m_$shortname.cpp";
my $shortname = module_shrink $extra;
my $extrafile = module_expand $extra;
my $modulepath = catfile $moduledir, $extrafile;
my $extrapath = catfile $extradir, $extrafile;

View File

@ -202,11 +202,11 @@ Quit from IRC and end your current session.
Returns the server's version information.
">
<helpop key="ping" title="/PING <servername> [:<servername>]" value="
<helpop key="ping" title="/PING <cookie> [<servername>]" value="
Ping a server. The server will answer with a PONG.
">
<helpop key="pong" title="/PONG <servername>" value="
<helpop key="pong" title="/PONG <cookie> [<servername>]" value="
Your client should send this to answer server PINGs. You
should not issue this command manually.
">
@ -572,9 +572,9 @@ the network.
Sends a message to all users with the +g snomask.
">
<helpop key="cban" title="/CBAN <channel> [<duration> [:<reason>]]" value="
Sets or removes a global channel ban. You must specify all three parameters
to add a ban, and one parameter to remove a ban (just the channel).
<helpop key="cban" title="/CBAN <channelmask> [<duration> [:<reason>]]" value="
Sets or removes a global channel based ban. You must specify all three parameters
to add a ban, and one parameter to remove a ban (just the channelmask).
The duration may be specified in seconds, or in the format
1y2w3d4h5m6s - meaning one year, two weeks, three days, four hours,

View File

@ -802,13 +802,8 @@
# #
# This configuration tag defines the maximum sizes of various types #
# on IRC, such as the maximum length of a channel name, and the #
# maximum length of a channel. Note that with the exception of the #
# identmax value all values given here are the exact values you would #
# expect to see on IRC. This contrasts with the older InspIRCd #
# releases where these values would be one character shorter than #
# defined to account for a null terminator on the end of the text. #
# #
# These values should match network-wide otherwise issues will occur. #
# maximum length of a channel. These values should match network-wide #
# otherwise issues will occur. #
# #
# The highest safe value you can set any of these options to is 500, #
# but it is recommended that you keep them somewhat #

View File

@ -183,6 +183,30 @@
# <anticaps lowercase="abcdefghijklmnopqrstuvwxyz"
# uppercase="ABCDEFGHIJKLMNOPQRSTUVWXYZ">
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
# Argon2 module: Allows other modules to generate Argon2 hashes,
# usually for cryptographic uses and security.
# This module makes the algorithms argon2i, argon2d and argon2id
# available for use.
# Note that this module is extra, and must be enabled explicitly
# to build. It depends on libargon2.
#<module name="argon2">
#
# memory: Memory hardness, in KiB. E.g. 131072 KiB = 128 MiB.
# iterations: Time hardness in iterations. (def. 3)
# lanes: How many parallel chains can be run. (def. 1)
# threads: Maximum amount of threads each invocation can spawn. (def. 1)
# length: Output length in bytes. (def. 32)
# saltlength: Salt length in bytes. (def. 16)
# version: Algorithm version, 10 or 13. (def. 13)
# The parameters can be customized as follows:
#<argon2 iterations="3" memory="131074" length="32" saltlength="16">
# Defines the parameters that are common for all the variants (i/d/id).
# Can be overridden on individual basis, e.g.
#<argon2i iterations="4">
#<argon2d memory="131074"
#<argon2id iterations="5" memory="262144" length="64" saltlength="32">
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
# Auditorium module: Adds channel mode +u which makes everyone else
# except you in the channel invisible, used for large meetings etc.
@ -1204,8 +1228,20 @@
# Closes the channel for N seconds if X users join in Y seconds.
#<module name="joinflood">
#
# The number of seconds to close the channel for:
#<joinflood duration="1m">
# duration: The number of seconds to close a channel for when it is
# being flooded with joins.
#
# bootwait: The number of seconds to disengage joinflood for after
# a server boots. This allows users to reconnect without
# being throttled by joinflood.
#
# splitwait: The number of seconds to disengage joinflood for after
# a server splits. This allows users to reconnect without
# being throttled by joinflood.
#
#<joinflood duration="1m"
# bootwait="30s"
# splitwait="30s">
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
# Anti auto rejoin: Adds support for prevention of auto-rejoin (+J).

View File

@ -1,7 +1,7 @@
# This file contains connect classes which are used by IRCCloud users.
# See https://www.irccloud.com for more information on IRCCloud and
# https://www.irccloud.com/networks for more information on supporting
# IRCloud on your network.
# IRCCloud on your network.
<connect name="IRCCloud"
parent="main"
@ -14,8 +14,14 @@
<connect name="IRCCloud-Hathersage" parent="IRCCloud" allow="192.184.8.73">
<connect name="IRCCloud-Highgate" parent="IRCCloud" allow="192.184.9.108">
<connect name="IRCCloud-Stonehaven" parent="IRCCloud" allow="192.184.8.103">
<connect name="IRCCloud-Tinside" parent="IRCCloud" allow="5.254.36.57">
<connect name="IRCCloud-Tooting" parent="IRCCloud" allow="192.184.10.9">
# This is not typically needed as each user has their own IPv6 but if you have
# This block has not yet been added to the connection pool but will be in the
# future. It is included here for future proofing purposes.
<connect name="IRCCloud-Unnamed" parent="IRCCloud" allow="5.254.36.56/29">
# These are not typically needed as each user has their own IPv6 but if you have
# <cidr:ipv6clone> set to a value lower than 128 you will need to enable this.
#<connect name="IRCCloud-IPv6" parent="IRCCloud" allow="2001:67c:2f08::/48">
#<connect name="IRCCloud-IPv6-1" parent="IRCCloud" allow="2001:67c:2f08::/48">
#<connect name="IRCCloud-IPV6-2" parent="IRCCloud" allow="2a03:5180:f::/64">

View File

@ -1,4 +0,0 @@
xE4 xC4 xF6 xD6 xFC xDC xDF xE4 xC4 xF6 xD6 xFC xDC xE9 xEB xF6 xEF xFC xE8 xE6 xC6 xE5 xC5 xF8 xD8 xC0 xC2 xE0 xE2 xC7 xE7 xC8 xC9 xCA xCB xE8 xE9 xEA xEB xCE xCF xEE xEF xD4 xF4 xD9 xDB xDC xF9 xFB xFC xFF xE1 xC1 xE9 xC9 xED xCD xF3 xD3 xFA xDA xFC xDC xF1 xD1 xC0 xC8 xC9 xCC xCD xD2 xD3 xD9 xDA xE0 xE8 xE9 xEC xED xF2 xF3 xF9 xFA xC0 xC8 xC9 xCC xCD xD2 xD3 xD9 xDA xE0 xE8 xE9 xEC xED xF2 xF3 xF9 xFA xE0 xC0 xE8 xC8 xE9 xC9 xED xCD xF2 xD2 xF3 xD3 xFA xDA xEF xCF xFC xDC xE5 xC5 xE4 xC4 xF6 xD6 xC6 xE6 xD6 xF6 xC1 xE1 xCD xED xD0 xF0 xDA xFA xD3 xF3 xDD xFD xDE xFE

View File

@ -663,11 +663,14 @@ struct ClientProtocol::Messages::Pong : public ClientProtocol::Message
{
/** Constructor.
* @param cookie Ping cookie. Must remain valid as long as this object is alive.
* @param server Pinged server. Must remain valid as long as this object is alive if non-empty.
*/
Pong(const std::string& cookie)
Pong(const std::string& cookie, const std::string& server = "")
: ClientProtocol::Message("PONG", ServerInstance->Config->ServerName)
{
PushParamRef(ServerInstance->Config->ServerName);
if (!server.empty())
PushParamRef(server);
PushParamRef(cookie);
}
};

View File

@ -112,6 +112,8 @@ class CoreExport ConfigTag : public refcountbase
class ServerLimits
{
public:
/** Maximum line length */
size_t MaxLine;
/** Maximum nickname length */
size_t NickMax;
/** Maximum channel length */
@ -130,8 +132,6 @@ class ServerLimits
size_t MaxReal;
/** Maximum away message length */
size_t MaxAway;
/** Maximum line length */
size_t MaxLine;
/** Maximum hostname length */
size_t MaxHost;

View File

@ -59,7 +59,7 @@ class CoreExport dynamic_reference_base : public interfacebase, public insp::int
inline void dynamic_reference_base::check()
{
if (!value)
throw ModuleException("Dynamic reference to '" + name + "' failed to resolve");
throw ModuleException("Dynamic reference to '" + name + "' failed to resolve. Are you missing a module?");
}
template<typename T>

View File

@ -205,23 +205,76 @@ enum Priority { PRIORITY_FIRST, PRIORITY_LAST, PRIORITY_BEFORE, PRIORITY_AFTER }
*/
enum Implementation
{
I_OnUserConnect, I_OnUserPreQuit, I_OnUserQuit, I_OnUserDisconnect, I_OnUserJoin, I_OnUserPart,
I_OnSendSnotice, I_OnUserPreJoin, I_OnUserPreKick, I_OnUserKick, I_OnOper,
I_OnUserPreInvite, I_OnUserInvite, I_OnUserPreMessage, I_OnUserPreNick,
I_OnUserPostMessage, I_OnUserMessageBlocked, I_OnMode, I_OnShutdown,
I_OnDecodeMetaData, I_OnAcceptConnection, I_OnUserInit, I_OnUserPostInit,
I_OnChangeHost, I_OnChangeRealName, I_OnAddLine, I_OnDelLine, I_OnExpireLine,
I_OnUserPostNick, I_OnPreMode, I_OnKill, I_OnLoadModule,
I_OnUnloadModule, I_OnBackgroundTimer, I_OnPreCommand, I_OnCheckReady, I_OnCheckInvite,
I_OnRawMode, I_OnCheckKey, I_OnCheckLimit, I_OnCheckBan, I_OnCheckChannelBan,
I_OnPreChangeHost, I_OnPreTopicChange, I_OnConnectionFail,
I_OnPostTopicChange, I_OnPostConnect, I_OnPostDeoper,
I_OnPreChangeRealName, I_OnUserRegister, I_OnChannelPreDelete, I_OnChannelDelete,
I_OnPostOper, I_OnPostCommand, I_OnCommandBlocked, I_OnPostJoin,
I_OnBuildNeighborList, I_OnGarbageCollect, I_OnSetConnectClass,
I_OnUserMessage, I_OnPassCompare, I_OnNumeric,
I_OnPreRehash, I_OnModuleRehash, I_OnChangeIdent, I_OnSetUserIP,
I_OnServiceAdd, I_OnServiceDel, I_OnUserWrite,
I_OnAcceptConnection,
I_OnAddLine,
I_OnBackgroundTimer,
I_OnBuildNeighborList,
I_OnChangeHost,
I_OnChangeIdent,
I_OnChangeRealHost,
I_OnChangeRealName,
I_OnChannelDelete,
I_OnChannelPreDelete,
I_OnCheckBan,
I_OnCheckChannelBan,
I_OnCheckInvite,
I_OnCheckKey,
I_OnCheckLimit,
I_OnCheckReady,
I_OnCommandBlocked,
I_OnConnectionFail,
I_OnDecodeMetaData,
I_OnDelLine,
I_OnExpireLine,
I_OnGarbageCollect,
I_OnKill,
I_OnLoadModule,
I_OnMode,
I_OnModuleRehash,
I_OnNumeric,
I_OnOper,
I_OnPassCompare,
I_OnPostCommand,
I_OnPostConnect,
I_OnPostDeoper,
I_OnPostJoin,
I_OnPostOper,
I_OnPostTopicChange,
I_OnPreChangeHost,
I_OnPreChangeRealName,
I_OnPreCommand,
I_OnPreMode,
I_OnPreRehash,
I_OnPreTopicChange,
I_OnRawMode,
I_OnSendSnotice,
I_OnServiceAdd,
I_OnServiceDel,
I_OnSetConnectClass,
I_OnSetUserIP,
I_OnShutdown,
I_OnUnloadModule,
I_OnUserConnect,
I_OnUserDisconnect,
I_OnUserInit,
I_OnUserInvite,
I_OnUserJoin,
I_OnUserKick,
I_OnUserMessage,
I_OnUserMessageBlocked,
I_OnUserPart,
I_OnUserPostInit,
I_OnUserPostMessage,
I_OnUserPostNick,
I_OnUserPreInvite,
I_OnUserPreJoin,
I_OnUserPreKick,
I_OnUserPreMessage,
I_OnUserPreNick,
I_OnUserPreQuit,
I_OnUserQuit,
I_OnUserRegister,
I_OnUserWrite,
I_END
};
@ -578,6 +631,13 @@ class CoreExport Module : public classbase, public usecountbase
*/
virtual void OnChangeHost(User* user, const std::string &newhost);
/** Called whenever a user's real hostname is changed.
* This event triggers after the host has been set.
* @param user The user whos host is being changed
* @param newhost The new hostname being set
*/
virtual void OnChangeRealHost(User* user, const std::string& newhost);
/** Called whenever a user's real name is changed.
* This event triggers after the name has been set.
* @param user The user who's real name is being changed

View File

@ -52,6 +52,8 @@ our @EXPORT = qw(CONFIGURE_CACHE_FILE
run_test
test_file
test_header
module_expand
module_shrink
write_configure_cache
get_compiler_info
find_compiler
@ -221,6 +223,18 @@ sub test_header($$;$) {
return !$?;
}
sub module_expand($) {
my $module = shift;
$module = "m_$module" unless $module =~ /^(?:m|core)_/;
$module = "$module.cpp" unless $module =~ /\.cpp$/;
return $module;
}
sub module_shrink($) {
my $module = basename shift;
return $module =~ s/(?:^m_|\.cpp$)//gr;
}
sub write_configure_cache(%) {
unless (-e CONFIGURE_DIRECTORY) {
print_format "Creating <|GREEN ${\abs2rel CONFIGURE_DIRECTORY, CONFIGURE_ROOT}|> ...\n";

View File

@ -27,7 +27,7 @@ use feature ':5.10';
use strict;
use warnings FATAL => qw(all);
use File::Basename qw(basename dirname);
use File::Basename qw(dirname);
use File::Spec::Functions qw(catdir);
use Exporter qw(import);
@ -89,13 +89,6 @@ sub __environment {
return $prefix . uc $suffix;
}
sub __module {
my $file = shift;
my $name = basename $file, '.cpp';
$name =~ s/^m_//;
return $name;
}
sub __error {
my ($file, @message) = @_;
push @message, '';
@ -133,7 +126,7 @@ sub __error {
push @message, 'at https://github.com/inspircd/inspircd/issues';
push @message, '';
push @message, 'You can also refer to the documentation page for this module at';
push @message, "https://docs.inspircd.org/3/modules/${\__module $file}";
push @message, "https://docs.inspircd.org/3/modules/${\module_shrink $file}";
}
push @message, '';
@ -184,19 +177,19 @@ sub __function_find_compiler_flags {
# Try to look up the compiler flags with pkg-config...
chomp(my $flags = `pkg-config --cflags $name ${\DIRECTIVE_ERROR_PIPE}`);
unless ($?) {
print_format "Found the <|GREEN $name|> compiler flags for <|GREEN ${\__module $file}|> using pkg-config: <|BOLD $flags|>\n";
print_format "Found the <|GREEN $name|> compiler flags for <|GREEN ${\module_shrink $file}|> using pkg-config: <|BOLD $flags|>\n";
return $flags;
}
# If looking up with pkg-config fails then check the environment...
my $key = __environment 'INSPIRCD_CXXFLAGS_', $name;
if (defined $ENV{$key}) {
print_format "Found the <|GREEN $name|> compiler flags for <|GREEN ${\__module $file}|> using the environment: <|BOLD $ENV{$key}|>\n";
print_format "Found the <|GREEN $name|> compiler flags for <|GREEN ${\module_shrink $file}|> using the environment: <|BOLD $ENV{$key}|>\n";
return $ENV{$key};
}
# We can't find it via pkg-config, via the environment, or via the defaults so give up.
__error $file, "unable to find the <|GREEN $name|> compiler flags for <|GREEN ${\__module $file}|>!";
__error $file, "unable to find the <|GREEN $name|> compiler flags for <|GREEN ${\module_shrink $file}|>!";
}
sub __function_find_linker_flags {
@ -205,19 +198,19 @@ sub __function_find_linker_flags {
# Try to look up the linker flags with pkg-config...
chomp(my $flags = `pkg-config --libs $name ${\DIRECTIVE_ERROR_PIPE}`);
unless ($?) {
print_format "Found the <|GREEN $name|> linker flags for <|GREEN ${\__module $file}|> using pkg-config: <|BOLD $flags|>\n";
print_format "Found the <|GREEN $name|> linker flags for <|GREEN ${\module_shrink $file}|> using pkg-config: <|BOLD $flags|>\n";
return $flags;
}
# If looking up with pkg-config fails then check the environment...
my $key = __environment 'INSPIRCD_CXXFLAGS_', $name;
if (defined $ENV{$key}) {
print_format "Found the <|GREEN $name|> linker flags for <|GREEN ${\__module $file}|> using the environment: <|BOLD $ENV{$key}|>\n";
print_format "Found the <|GREEN $name|> linker flags for <|GREEN ${\module_shrink $file}|> using the environment: <|BOLD $ENV{$key}|>\n";
return $ENV{$key};
}
# We can't find it via pkg-config, via the environment, or via the defaults so give up.
__error $file, "unable to find the <|GREEN $name|> linker flags for <|GREEN ${\__module $file}|>!";
__error $file, "unable to find the <|GREEN $name|> linker flags for <|GREEN ${\module_shrink $file}|>!";
}
sub __function_require_compiler {
@ -285,18 +278,18 @@ sub __function_vendor_directory {
# Try to look the directory up in the environment...
my $key = __environment 'INSPIRCD_VENDOR_', $name;
if (defined $ENV{$key}) {
print_format "Found the <|GREEN $name|> vendor directory for <|GREEN ${\__module $file}|> using the environment: <|BOLD $ENV{$key}|>\n";
print_format "Found the <|GREEN $name|> vendor directory for <|GREEN ${\module_shrink $file}|> using the environment: <|BOLD $ENV{$key}|>\n";
return $ENV{$key};
}
my $directory = catdir(VENDOR_DIRECTORY, $name);
if (-d $directory) {
print_format "Using the default <|GREEN $name|> vendor directory for <|GREEN ${\__module $file}|>: <|BOLD $directory|>\n";
print_format "Using the default <|GREEN $name|> vendor directory for <|GREEN ${\module_shrink $file}|>: <|BOLD $directory|>\n";
return $directory;
}
# We can't find it via the environment or via the filesystem so give up.
__error $file, "unable to find the <|GREEN $name|> vendor directory for <|GREEN ${\__module $file}|>!";
__error $file, "unable to find the <|GREEN $name|> vendor directory for <|GREEN ${\module_shrink $file}|>!";
}
sub __function_warning {

View File

@ -132,7 +132,6 @@ ifeq ($(INSPIRCD_DEBUG), 3)
HEADER = std-header
DBGOK=1
endif
FOOTER = finishmessage
MAKEFLAGS += --no-print-directory
@ -163,7 +162,6 @@ TARGET = all
ifdef INSPIRCD_TARGET
HEADER = mod-header
FOOTER = mod-footer
TARGET = $(INSPIRCD_TARGET)
endif
@ -171,7 +169,7 @@ ifeq ($(DBGOK), 0)
HEADER = unknown-debug-level
endif
all: $(FOOTER)
all: finishmessage
target: $(HEADER)
$(MAKEENV) perl make/calcdep.pl
@ -197,10 +195,6 @@ debug-header:
mod-header:
@echo 'Building specific targets:'
mod-footer: target
@echo 'To install, copy $(BUILDPATH)/$(TARGET) to $(MODPATH)'
@echo 'Or, run "make install"'
std-header:
@echo "*************************************"
@echo "* BUILDING INSPIRCD *"

View File

@ -38,17 +38,17 @@
#include <iostream>
ServerLimits::ServerLimits(ConfigTag* tag)
: NickMax(tag->getUInt("maxnick", 30))
, ChanMax(tag->getUInt("maxchan", 64))
, MaxModes(tag->getUInt("maxmodes", 20))
, IdentMax(tag->getUInt("maxident", 10))
, MaxQuit(tag->getUInt("maxquit", 255))
, MaxTopic(tag->getUInt("maxtopic", 307))
, MaxKick(tag->getUInt("maxkick", 255))
, MaxReal(tag->getUInt("maxreal", 128))
, MaxAway(tag->getUInt("maxaway", 200))
, MaxLine(tag->getUInt("maxline", 512))
, MaxHost(tag->getUInt("maxhost", 64))
: MaxLine(tag->getUInt("maxline", 512, 512))
, NickMax(tag->getUInt("maxnick", 30, 1, MaxLine))
, ChanMax(tag->getUInt("maxchan", 64, 1, MaxLine))
, MaxModes(tag->getUInt("maxmodes", 20, 1))
, IdentMax(tag->getUInt("maxident", 10, 1))
, MaxQuit(tag->getUInt("maxquit", 255, 0, MaxLine))
, MaxTopic(tag->getUInt("maxtopic", 307, 1, MaxLine))
, MaxKick(tag->getUInt("maxkick", 255, 1, MaxLine))
, MaxReal(tag->getUInt("maxreal", 128, 1, MaxLine))
, MaxAway(tag->getUInt("maxaway", 200, 1, MaxLine))
, MaxHost(tag->getUInt("maxhost", 64, 1, MaxLine))
{
}

View File

@ -83,6 +83,7 @@ void ISupportManager::Build()
{ "MAXTARGETS", ConvToStr(ServerInstance->Config->MaxTargets) },
{ "MODES", ConvToStr(ServerInstance->Config->Limits.MaxModes) },
{ "NETWORK", ServerInstance->Config->Network },
{ "NAMELEN", ConvToStr(ServerInstance->Config->Limits.MaxReal) },
{ "NICKLEN", ConvToStr(ServerInstance->Config->Limits.NickMax) },
{ "PREFIX", ServerInstance->Modes.BuildPrefixes() },
{ "STATUSMSG", ServerInstance->Modes.BuildPrefixes(false) },

View File

@ -64,9 +64,9 @@ class CommandPing : public SplitCommand
/** Constructor for ping.
*/
CommandPing(Module* parent)
: SplitCommand(parent, "PING", 1, 2)
: SplitCommand(parent, "PING", 1)
{
syntax = { "<servername> [:<servername>]" };
syntax = { "<cookie> [<servername>]" };
}
/** Handle command.
@ -76,7 +76,14 @@ class CommandPing : public SplitCommand
*/
CmdResult HandleLocal(LocalUser* user, const Params& parameters) override
{
ClientProtocol::Messages::Pong pong(parameters[0]);
size_t origin = parameters.size() > 1 ? 1 : 0;
if (parameters[origin].empty())
{
user->WriteNumeric(ERR_NOORIGIN, "No origin specified");
return CmdResult::FAILURE;
}
ClientProtocol::Messages::Pong pong(parameters[0], origin ? parameters[1] : "");
user->Send(ServerInstance->GetRFCEvents().pong, pong);
return CmdResult::SUCCESS;
}
@ -90,10 +97,10 @@ class CommandPong : public Command
/** Constructor for pong.
*/
CommandPong(Module* parent)
: Command(parent, "PONG", 0, 1)
: Command(parent, "PONG", 1)
{
Penalty = 0;
syntax = { "<ping-text>" };
syntax = { "<cookie> [<servername>]" };
}
/** Handle command.
@ -103,6 +110,13 @@ class CommandPong : public Command
*/
CmdResult Handle(User* user, const Params& parameters) override
{
size_t origin = parameters.size() > 1 ? 1 : 0;
if (parameters[origin].empty())
{
user->WriteNumeric(ERR_NOORIGIN, "No origin specified");
return CmdResult::FAILURE;
}
// set the user as alive so they survive to next ping
LocalUser* localuser = IS_LOCAL(user);
if (localuser)

View File

@ -24,6 +24,12 @@
#include "listmode.h"
#include "modules/away.h"
enum
{
// From RFC 1459.
ERR_NOORIGIN = 409
};
class MessageWrapper
{
std::string prefix;

View File

@ -82,6 +82,16 @@ class CoreModXLine : public Module
user->CheckLines(true);
}
void OnChangeRealHost(User* user, const std::string& newhost) override
{
LocalUser* luser = IS_LOCAL(user);
if (!luser || luser->quitting)
return;
luser->exempt = (ServerInstance->XLines->MatchesLine("E", user) != NULL);
luser->CheckLines(false);
}
ModResult OnUserPreNick(LocalUser* user, const std::string& newnick) override
{
// Check Q-lines (for local nick changes only, remote servers have our Q-lines to enforce themselves)

View File

@ -135,6 +135,7 @@ void Module::OnUserInvite(User*, User*, Channel*, time_t, unsigned int, CUList&
void Module::OnPostTopicChange(User*, Channel*, const std::string&) { DetachEvent(I_OnPostTopicChange); }
void Module::OnDecodeMetaData(Extensible*, const std::string&, const std::string&) { DetachEvent(I_OnDecodeMetaData); }
void Module::OnChangeHost(User*, const std::string&) { DetachEvent(I_OnChangeHost); }
void Module::OnChangeRealHost(User*, const std::string&) { DetachEvent(I_OnChangeRealHost); }
void Module::OnChangeRealName(User*, const std::string&) { DetachEvent(I_OnChangeRealName); }
void Module::OnChangeIdent(User*, const std::string&) { DetachEvent(I_OnChangeIdent); }
void Module::OnAddLine(User*, XLine*) { DetachEvent(I_OnAddLine); }

View File

@ -0,0 +1,194 @@
/*
* InspIRCd -- Internet Relay Chat Daemon
*
* Copyright (C) 2020 Daniel Vassdal <shutter@canternet.org>
*
* 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/>.
*/
/// $CompilerFlags: find_compiler_flags("libargon2" "")
/// $LinkerFlags: find_linker_flags("libargon2" "-llibargon2")
/// $PackageInfo: require_system("arch") argon2 pkgconf
/// $PackageInfo: require_system("darwin") argon2 pkg-config
/// $PackageInfo: require_system("debian" "9.0") libargon2-0 pkg-config
/// $PackageInfo: require_system("ubuntu" "18.04") libargon2-0-dev pkg-config
#include "inspircd.h"
#include "modules/hash.h"
#include <argon2.h>
class ProviderConfig
{
private:
static Argon2_version SanitizeArgon2Version(unsigned long version)
{
// Note, 10 is 0x10, and 13 is 0x13. Referring to it as
// dec 10 or 13 in the config file, for the name to
// match better.
switch (version)
{
case 10:
return ARGON2_VERSION_10;
case 13:
return ARGON2_VERSION_13;
}
ServerInstance->Logs.Log("MODULE", LOG_DEFAULT, "Unknown Argon2 version (%lu) specified; assuming 13",
version);
return ARGON2_VERSION_13;
}
public:
uint32_t iterations;
uint32_t lanes;
uint32_t memory;
uint32_t outlen;
uint32_t saltlen;
uint32_t threads;
Argon2_version version;
ProviderConfig()
{
// Nothing interesting happens here.
}
ProviderConfig(const std::string& tagname, ProviderConfig* def)
{
ConfigTag* tag = ServerInstance->Config->ConfValue(tagname);
uint32_t def_iterations = def ? def->iterations : 3;
this->iterations = tag->getUInt("iterations", def_iterations, 1);
uint32_t def_lanes = def ? def->lanes : 1;
this->lanes = tag->getUInt("lanes", def_lanes, ARGON2_MIN_LANES, ARGON2_MAX_LANES);
uint32_t def_memory = def ? def->memory : 131072; // 128 MiB
this->memory = tag->getUInt("memory", def_memory, ARGON2_MIN_MEMORY, ARGON2_MAX_MEMORY);
uint32_t def_outlen = def ? def->outlen : 32;
this->outlen = tag->getUInt("length", def_outlen, ARGON2_MIN_OUTLEN, ARGON2_MAX_OUTLEN);
uint32_t def_saltlen = def ? def->saltlen : 16;
this->saltlen = tag->getUInt("saltlength", def_saltlen, ARGON2_MIN_SALT_LENGTH, ARGON2_MAX_SALT_LENGTH);
uint32_t def_threads = def ? def->threads : 1;
this->threads = tag->getUInt("threads", def_threads, ARGON2_MIN_THREADS, ARGON2_MAX_THREADS);
uint32_t def_version = def ? def->version : 13;
this->version = SanitizeArgon2Version(tag->getUInt("version", def_version));
}
};
class HashArgon2 : public HashProvider
{
private:
const Argon2_type argon2Type;
public:
ProviderConfig config;
bool Compare(const std::string& input, const std::string& hash) override
{
int result = argon2_verify(
hash.c_str(),
input.c_str(),
input.length(),
argon2Type);
return result == ARGON2_OK;
}
std::string GenerateRaw(const std::string& data) override
{
const std::string salt = ServerInstance->GenRandomStr(config.saltlen, false);
size_t encodedLen = argon2_encodedlen(
config.iterations,
config.memory,
config.lanes,
config.saltlen,
config.outlen,
argon2Type);
std::vector<char> raw_data(config.outlen);
std::vector<char> encoded_data(encodedLen + 1);
int argonResult = argon2_hash(
config.iterations,
config.memory,
config.threads,
data.c_str(),
data.length(),
salt.c_str(),
salt.length(),
&raw_data[0],
raw_data.size(),
&encoded_data[0],
encoded_data.size(),
argon2Type,
config.version);
if (argonResult != ARGON2_OK)
throw ModuleException("Argon2 hashing failed!: " + std::string(argon2_error_message(argonResult)));
// This isn't the raw version, but we don't have
// the facilities to juggle around the extra state required
// to do anything useful with them if we don't encode them.
// So we pretend this is the raw version, and instead make
// ToPrintable return its input.
return std::string(&encoded_data[0], encoded_data.size());
}
std::string ToPrintable(const std::string& raw) override
{
return raw;
}
HashArgon2(Module* parent, const std::string& hashName, Argon2_type type)
: HashProvider(parent, hashName)
, argon2Type(type)
{
}
};
class ModuleArgon2 : public Module
{
private:
HashArgon2 argon2i;
HashArgon2 argon2d;
HashArgon2 argon2id;
public:
ModuleArgon2()
: Module(VF_VENDOR, "Allows other modules to generate Argon2 hashes.")
, argon2i(this, "argon2i", Argon2_i)
, argon2d(this, "argon2d", Argon2_d)
, argon2id(this, "argon2id", Argon2_id)
{
}
void ReadConfig(ConfigStatus& status) override
{
ProviderConfig defaultConfig("argon2", NULL);
argon2i.config = ProviderConfig("argon2i", &defaultConfig);
argon2d.config = ProviderConfig("argon2d", &defaultConfig);
argon2id.config = ProviderConfig("argon2id", &defaultConfig);
}
};
MODULE_INIT(ModuleArgon2)

View File

@ -58,7 +58,7 @@ public:
bool Matches(const std::string& s) override
{
return irc::equals(matchtext, s);
return InspIRCd::Match(s, matchtext);
}
const std::string& Displayable() override
@ -95,7 +95,7 @@ class CommandCBan : public Command
CommandCBan(Module* Creator) : Command(Creator, "CBAN", 1, 3)
{
access_needed = CmdAccess::OPERATOR;
syntax = { "<channel> [<duration> [:<reason>]]" };
syntax = { "<channelmask> [<duration> [:<reason>]]" };
}
CmdResult Handle(User* user, const Params& parameters) override
@ -209,6 +209,11 @@ class ModuleCBan : public Module, public Stats::EventListener
return MOD_RES_PASSTHRU;
}
void GetLinkData(std::string& data) override
{
data = "glob";
}
};
MODULE_INIT(ModuleCBan)

View File

@ -221,6 +221,8 @@ class CommandCheck : public Command
std::string classname = loctarg->GetClass()->name;
if (!classname.empty())
context.Write("connectclass", classname);
context.Write("exempt", loctarg->exempt ? "yes" : "no");
}
else
context.Write("onip", targuser->GetIPString());

View File

@ -143,8 +143,16 @@ class CloakUser : public ModeHandler
if (!cloaks)
{
/* Force creation of missing cloak */
creator->OnUserConnect(user);
cloaks = ext.get(user);
try
{
creator->OnUserConnect(user);
cloaks = ext.get(user);
}
catch (CoreException& modexcept)
{
ServerInstance->Logs.Log(MODNAME, LOG_DEFAULT, "Exception caught when generating cloak: " + modexcept.GetReason());
return MODEACTION_DENY;
}
}
// If we have a cloak then set the hostname.

View File

@ -253,17 +253,16 @@ class ModuleDNSBL : public Module, public Stats::EventListener
*/
DNSBLConfEntry::EnumBanaction str2banaction(const std::string &action)
{
if(action.compare("KILL")==0)
if (stdalgo::string::equalsci(action, "kill"))
return DNSBLConfEntry::I_KILL;
if(action.compare("KLINE")==0)
if (stdalgo::string::equalsci(action, "kline"))
return DNSBLConfEntry::I_KLINE;
if(action.compare("ZLINE")==0)
if (stdalgo::string::equalsci(action, "zline"))
return DNSBLConfEntry::I_ZLINE;
if(action.compare("GLINE")==0)
if (stdalgo::string::equalsci(action, "gline"))
return DNSBLConfEntry::I_GLINE;
if(action.compare("MARK")==0)
if (stdalgo::string::equalsci(action, "mark"))
return DNSBLConfEntry::I_MARK;
return DNSBLConfEntry::I_UNKNOWN;
}
public:
@ -294,7 +293,7 @@ class ModuleDNSBL : public Module, public Stats::EventListener
e->name = tag->getString("name");
e->ident = tag->getString("ident");
e->host = tag->getString("host");
e->reason = tag->getString("reason");
e->reason = tag->getString("reason", "Your IP has been blacklisted.", 1);
e->domain = tag->getString("domain");
if (stdalgo::string::equalsci(tag->getString("type"), "bitmask"))
@ -336,13 +335,6 @@ class ModuleDNSBL : public Module, public Stats::EventListener
}
else
{
if (e->reason.empty())
{
std::string location = tag->getTagLocation();
ServerInstance->SNO.WriteGlobalSno('d', "DNSBL(%s): empty reason, using defaults", location.c_str());
e->reason = "Your IP has been blacklisted.";
}
/* add it, all is ok */
newentries.push_back(e);
}

View File

@ -24,6 +24,7 @@
#include "inspircd.h"
#include "modules/server.h"
enum
{
@ -132,14 +133,22 @@ class JoinFlood : public ParamMode<JoinFlood, SimpleExtItem<joinfloodsettings> >
}
};
class ModuleJoinFlood : public Module
class ModuleJoinFlood
: public Module
, public ServerProtocol::LinkEventListener
{
private:
JoinFlood jf;
time_t ignoreuntil;
unsigned long bootwait;
unsigned long splitwait;
public:
ModuleJoinFlood()
: Module(VF_VENDOR, "Adds channel mode j (joinflood) which helps protect against spammers which mass-join channels.")
, ServerProtocol::LinkEventListener(this)
, jf(this)
, ignoreuntil(0)
{
}
@ -147,6 +156,16 @@ class ModuleJoinFlood : public Module
{
ConfigTag* tag = ServerInstance->Config->ConfValue("joinflood");
duration = tag->getDuration("duration", 60, 10, 600);
bootwait = tag->getDuration("bootwait", 30);
splitwait = tag->getDuration("splitwait", 30);
ignoreuntil = ServerInstance->startup_time + bootwait;
}
void OnServerSplit(const Server* server, bool error) override
{
if (splitwait)
ignoreuntil = ServerInstance->Time() + splitwait;
}
ModResult OnUserPreJoin(LocalUser* user, Channel* chan, const std::string& cname, std::string& privs, const std::string& keygiven) override
@ -166,7 +185,7 @@ class ModuleJoinFlood : public Module
void OnUserJoin(Membership* memb, bool sync, bool created, CUList& excepts) override
{
/* We arent interested in JOIN events caused by a network burst */
if (sync)
if (sync || ignoreuntil > ServerInstance->Time())
return;
joinfloodsettings *f = jf.ext.get(memb->chan);

View File

@ -1069,6 +1069,7 @@ void User::ChangeRealHost(const std::string& host, bool resetdisplay)
if (!changehost)
return;
FOREACH_MOD(OnChangeRealHost, (this, host));
realhost = host;
this->InvalidateCache();
}

10
vendor/README.md vendored
View File

@ -22,16 +22,6 @@ This directory contains vendored dependencies that are shipped with InspIRCd to
**Website** &mdash; [https://github.com/nodejs/http-parser](https://github.com/nodejs/http-parser)
## optional-lite
**Author** &mdash; [Martin Moene](mailto:martin.moene@gmail.com)
**License** &mdash; Boost Software License
**Version** &mdash; v3.2.0
**Website** &mdash; [https://github.com/martinmoene/optional-lite](https://github.com/martinmoene/optional-lite)
## sha2
**Author** &mdash; [Olivier Gay](mailto:olivier.gay@a3.epfl.ch)