From 2cdd31173504ee0fecdb2ce56c2f4f893e4b0a7b Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Tue, 16 Nov 2021 18:49:08 +0000 Subject: Document ConnectClass and reorder it to avoid unnecessary padding. --- include/typedefs.h | 2 +- include/users.h | 121 ++++++++++++++++++++++++----------------------------- src/users.cpp | 56 ++++++++++++------------- 3 files changed, 83 insertions(+), 96 deletions(-) diff --git a/include/typedefs.h b/include/typedefs.h index 8a7b59159..063ee23cb 100644 --- a/include/typedefs.h +++ b/include/typedefs.h @@ -49,7 +49,7 @@ class User; class XLine; class XLineManager; class XLineFactory; -struct ConnectClass; +class ConnectClass; class ModResult; namespace ClientProtocol diff --git a/include/users.h b/include/users.h index d6cac1196..03e3afacc 100644 --- a/include/users.h +++ b/include/users.h @@ -71,105 +71,92 @@ enum UserType { USERTYPE_SERVER = 3 }; -/** Holds information relevant to <connect allow> and <connect deny> tags in the config file. - */ -struct CoreExport ConnectClass : public refcountbase +/** Represents \ class tags from the server config */ +class CoreExport ConnectClass : public refcountbase { + public: + /** The synthesized (with all inheritance applied) config tag this class was read from. */ reference config; - /** Type of line, either CC_ALLOW or CC_DENY - */ - char type; - /** True if this class uses fake lag to manage flood, false if it kills */ - bool fakelag; + /** The hosts that this user can connect from as a string. */ + std::string host; - /** Connect class name - */ + /** The hosts that this user can connect from as a vector. */ + std::vector hosts; + + /** The name of this connect class. */ std::string name; - /** Max time to register the connection in seconds - */ - unsigned int registration_timeout; + /** If non-empty then the password a user must specify in PASS to be assigned to this class. */ + std::string password; - /** Hosts that this user can connect from as a string. */ - std::string host; + /** If non-empty then the hash algorithm that the password field is hashed with. */ + std::string passwordhash; - /** Hosts that this user can connect from as a vector. */ - std::vector hosts; + /** If non-empty then the server ports which a user has to be connecting on. */ + insp::flat_set ports; - /** Number of seconds between pings for this line - */ - unsigned int pingtime; + /** The type of class this. */ + char type; - /** Maximum size of sendq for users in this class (bytes) - * Users cannot send commands if they go over this limit - */ - unsigned long softsendqmax; + /** Whether fake lag is used by this class. */ + bool fakelag:1; - /** Maximum size of sendq for users in this class (bytes) - * Users are killed if they go over this limit - */ - unsigned long hardsendqmax; + /** Whether to warn server operators about the limit for this class being reached. */ + bool maxconnwarn:1; - /** Maximum size of recvq for users in this class (bytes) - */ - unsigned long recvqmax; + /** Whether the DNS hostnames of users in this class should be resolved. */ + bool resolvehostnames:1; - /** Seconds worth of penalty before penalty system activates - */ - unsigned int penaltythreshold; + /** The maximum number of channels that users in this class can join. */ + unsigned int maxchans; - /** Maximum rate of commands (units: millicommands per second) */ - unsigned int commandrate; + /** The amount of penalty that a user in this class can have before the penalty system activates. */ + unsigned int penaltythreshold; - /** Local max when connecting by this connection class - */ - unsigned long maxlocal; + /** The number of seconds between keepalive checks for idle clients in this class. */ + unsigned int pingtime; - /** Global max when connecting by this connection class - */ - unsigned long maxglobal; + /** The number of seconds that connecting users have to register within in this class. */ + unsigned int registration_timeout; - /** True if max connections for this class is hit and a warning is wanted - */ - bool maxconnwarn; + /** Maximum rate of commands (units: millicommands per second) */ + unsigned int commandrate; - /** Max channels for this class - */ - unsigned int maxchans; + /** The maximum number of bytes that users in this class can have in their send queue before they are disconnected. */ + unsigned long hardsendqmax; - /** How many users may be in this connect class before they are refused? - * (0 = no limit = default) - */ + /** The maximum number of users in this class that can connect to the local server from one host. */ unsigned long limit; - /** If set to true, no user DNS lookups are to be performed - */ - bool resolvehostnames; + /** The maximum number of users in this class that can connect to the entire network from one host. */ + unsigned long maxglobal; - /** - * If non-empty the server ports which this user has to be using - */ - insp::flat_set ports; + /** The maximum number of users that can be in this class on the local server. */ + unsigned long maxlocal; - /** If non-empty then the password a user must specify in PASS to be assigned to this class. */ - std::string password; + /** The maximum number of bytes that users in this class can have in their receive queue before they are disconnected. */ + unsigned long recvqmax; - /** If non-empty then the hash algorithm that the password field is hashed with. */ - std::string passwordhash; + /** The maximum number of bytes that users in this class can have in their send queue before their commands stop being processed. */ + unsigned long softsendqmax; - /** Create a new connect class with no settings. - */ + /** Creates a new connect class from a config tag */ ConnectClass(ConfigTag* tag, char type, const std::string& mask); - /** Create a new connect class with inherited settings. - */ + + /** Creates a new connect class with a parent from a config tag. */ ConnectClass(ConfigTag* tag, char type, const std::string& mask, const ConnectClass& parent); - /** Update the settings in this block to match the given block */ + /** Update the settings in this block to match the given class */ void Update(const ConnectClass* newSettings); + /** Retrieves the name of this connect class. */ const std::string& GetName() const { return name; } + + /** Retrieves the hosts that this user can connect from as a string. */ const std::string& GetHost() const { return host; } + + /** Retrieves the hosts that this user can connect from as a vector. */ const std::vector& GetHosts() const { return hosts; } /** Returns the registration timeout diff --git a/src/users.cpp b/src/users.cpp index 4e91c31d1..1ec7d9423 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -1259,23 +1259,23 @@ const std::string& FakeUser::GetFullRealHost() ConnectClass::ConnectClass(ConfigTag* tag, char t, const std::string& mask) : config(tag) + , host(mask) + , name("unnamed") , type(t) , fakelag(true) - , name("unnamed") - , registration_timeout(0) - , host(mask) - , pingtime(0) - , softsendqmax(0) - , hardsendqmax(0) - , recvqmax(0) - , penaltythreshold(0) - , commandrate(0) - , maxlocal(0) - , maxglobal(0) , maxconnwarn(true) + , resolvehostnames(true) , maxchans(0) + , penaltythreshold(0) + , pingtime(0) + , registration_timeout(0) + , commandrate(0) + , hardsendqmax(0) , limit(0) - , resolvehostnames(true) + , maxglobal(0) + , maxlocal(0) + , recvqmax(0) + , softsendqmax(0) { irc::spacesepstream hoststream(host); for (std::string hostentry; hoststream.GetToken(hostentry); ) @@ -1322,25 +1322,25 @@ ConnectClass::ConnectClass(ConfigTag* tag, char t, const std::string& mask, cons void ConnectClass::Update(const ConnectClass* src) { config = src->config; - type = src->type; - fakelag = src->fakelag; - name = src->name; - registration_timeout = src->registration_timeout; host = src->host; hosts = src->hosts; - pingtime = src->pingtime; - softsendqmax = src->softsendqmax; - hardsendqmax = src->hardsendqmax; - recvqmax = src->recvqmax; - penaltythreshold = src->penaltythreshold; - commandrate = src->commandrate; - maxlocal = src->maxlocal; - maxglobal = src->maxglobal; + name = src->name; + password = src->password; + passwordhash = src->passwordhash; + ports = src->ports; + type = src->type; + fakelag = src->fakelag; maxconnwarn = src->maxconnwarn; + resolvehostnames = src->resolvehostnames; maxchans = src->maxchans; + penaltythreshold = src->penaltythreshold; + pingtime = src->pingtime; + registration_timeout = src->registration_timeout; + commandrate = src->commandrate; + hardsendqmax = src->hardsendqmax; limit = src->limit; - resolvehostnames = src->resolvehostnames; - ports = src->ports; - password = src->password; - passwordhash = src->passwordhash; + maxglobal = src->maxglobal; + maxlocal = src->maxlocal; + recvqmax = src->recvqmax; + softsendqmax = src->softsendqmax; } -- cgit v1.3.1-10-gc9f91 From 4aac3532f5b302efa4947e08b4de7a6bb47a0e5e Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Tue, 16 Nov 2021 19:17:35 +0000 Subject: Use a mode reference in the messageflood module. --- src/modules/m_messageflood.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/modules/m_messageflood.cpp b/src/modules/m_messageflood.cpp index 216c20c03..4c79318fc 100644 --- a/src/modules/m_messageflood.cpp +++ b/src/modules/m_messageflood.cpp @@ -114,6 +114,7 @@ class ModuleMsgFlood , public CTCTags::EventListener { private: + ChanModeReference banmode; CheckExemption::EventProvider exemptionprov; MsgFlood mf; double notice; @@ -123,6 +124,7 @@ private: public: ModuleMsgFlood() : CTCTags::EventListener(this) + , banmode(this, "ban") , exemptionprov(this) , mf(this) { @@ -159,7 +161,7 @@ private: if (f->ban) { Modes::ChangeList changelist; - changelist.push_add(ServerInstance->Modes->FindMode('b', MODETYPE_CHANNEL), "*!*@" + user->GetDisplayedHost()); + changelist.push_add(*banmode, "*!*@" + user->GetDisplayedHost()); ServerInstance->Modes->Process(ServerInstance->FakeClient, dest, NULL, changelist); } -- cgit v1.3.1-10-gc9f91 From 23b4b24bed9c81000ebe650d6fb85d46ce30b47d Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Tue, 16 Nov 2021 19:35:15 +0000 Subject: Use a mode reference in the anticaps module. --- src/modules/m_anticaps.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/modules/m_anticaps.cpp b/src/modules/m_anticaps.cpp index 92a9b9ff9..7c59cc2ba 100644 --- a/src/modules/m_anticaps.cpp +++ b/src/modules/m_anticaps.cpp @@ -157,6 +157,7 @@ class AntiCapsMode : public ParamMode uppercase; std::bitset lowercase; @@ -169,7 +170,7 @@ class ModuleAntiCaps : public Module banmask.append(user->GetDisplayedHost()); Modes::ChangeList changelist; - changelist.push_add(ServerInstance->Modes->FindMode('b', MODETYPE_CHANNEL), banmask); + changelist.push_add(*banmode, banmask); ServerInstance->Modes->Process(ServerInstance->FakeClient, channel, NULL, changelist); } @@ -180,7 +181,8 @@ class ModuleAntiCaps : public Module public: ModuleAntiCaps() - : exemptionprov(this) + : banmode(this, "ban") + , exemptionprov(this) , mode(this) { } -- cgit v1.3.1-10-gc9f91 From 1044dce33d8a1a9a11baa2d6a034adb386a49cf4 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Tue, 16 Nov 2021 19:37:51 +0000 Subject: Clean up the banredirect module. --- src/modules/m_banredirect.cpp | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/modules/m_banredirect.cpp b/src/modules/m_banredirect.cpp index 579bf9d32..481059e59 100644 --- a/src/modules/m_banredirect.cpp +++ b/src/modules/m_banredirect.cpp @@ -51,13 +51,14 @@ typedef std::vector BanRedirectList; class BanRedirect : public ModeWatcher { - ChanModeReference ban; public: - SimpleExtItem extItem; + ChanModeReference banmode; + SimpleExtItem redirectlist; + BanRedirect(Module* parent) : ModeWatcher(parent, "ban", MODETYPE_CHANNEL) - , ban(parent, "ban") - , extItem("banredirect", ExtensionItem::EXT_CHANNEL, parent) + , banmode(parent, "ban") + , redirectlist("banredirect", ExtensionItem::EXT_CHANNEL, parent) { } @@ -84,7 +85,7 @@ class BanRedirect : public ModeWatcher if (param.find('#') == std::string::npos) return true; - ListModeBase* banlm = static_cast(*ban); + ListModeBase* banlm = static_cast(*banmode); unsigned int maxbans = banlm->GetLimit(channel); ListModeBase::ModeList* list = banlm->GetList(channel); if ((list) && (adding) && (maxbans <= list->size())) @@ -183,11 +184,11 @@ class BanRedirect : public ModeWatcher if(adding) { /* It's a properly valid redirecting ban, and we're adding it */ - redirects = extItem.get(channel); + redirects = redirectlist.get(channel); if (!redirects) { redirects = new BanRedirectList; - extItem.set(channel, redirects); + redirectlist.set(channel, redirects); } else { @@ -214,7 +215,7 @@ class BanRedirect : public ModeWatcher else { /* Removing a ban, if there's no extensible there are no redirecting bans and we're fine. */ - redirects = extItem.get(channel); + redirects = redirectlist.get(channel); if (redirects) { /* But there were, so we need to remove the matching one if there is one */ @@ -227,7 +228,7 @@ class BanRedirect : public ModeWatcher if(redirects->empty()) { - extItem.unset(channel); + redirectlist.unset(channel); } break; @@ -247,14 +248,15 @@ class BanRedirect : public ModeWatcher class ModuleBanRedirect : public Module { - BanRedirect re; + private: + BanRedirect banwatcher; bool nofollow; ChanModeReference limitmode; ChanModeReference redirectmode; public: ModuleBanRedirect() - : re(this) + : banwatcher(this) , nofollow(false) , limitmode(this, "limit") , redirectmode(this, "redirect") @@ -266,18 +268,17 @@ class ModuleBanRedirect : public Module if (type == ExtensionItem::EXT_CHANNEL) { Channel* chan = static_cast(item); - BanRedirectList* redirects = re.extItem.get(chan); + BanRedirectList* redirects = banwatcher.redirectlist.get(chan); if(redirects) { - ModeHandler* ban = ServerInstance->Modes->FindMode('b', MODETYPE_CHANNEL); Modes::ChangeList changelist; for(BanRedirectList::iterator i = redirects->begin(); i != redirects->end(); i++) - changelist.push_remove(ban, i->targetchan.insert(0, i->banmask)); + changelist.push_remove(*banwatcher.banmode, i->targetchan.insert(0, i->banmask)); for(BanRedirectList::iterator i = redirects->begin(); i != redirects->end(); i++) - changelist.push_add(ban, i->banmask); + changelist.push_add(*banwatcher.banmode, i->banmask); ServerInstance->Modes->Process(ServerInstance->FakeClient, chan, NULL, changelist, ModeParser::MODE_LOCALONLY); } @@ -288,7 +289,7 @@ class ModuleBanRedirect : public Module { if (chan) { - BanRedirectList* redirects = re.extItem.get(chan); + BanRedirectList* redirects = banwatcher.redirectlist.get(chan); if (redirects) { -- cgit v1.3.1-10-gc9f91 From b8fc612f43a61afa0ccff7016fda1af38f75d976 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Tue, 16 Nov 2021 19:39:43 +0000 Subject: Use a mode reference in the repeat module. --- src/modules/m_repeat.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/modules/m_repeat.cpp b/src/modules/m_repeat.cpp index bda5dd4c4..c114d9396 100644 --- a/src/modules/m_repeat.cpp +++ b/src/modules/m_repeat.cpp @@ -363,12 +363,15 @@ class RepeatMode : public ParamMode > class RepeatModule : public Module { + private: + ChanModeReference banmode; CheckExemption::EventProvider exemptionprov; RepeatMode rm; public: RepeatModule() - : exemptionprov(this) + : banmode(this, "ban") + , exemptionprov(this) , rm(this) { } @@ -410,7 +413,7 @@ class RepeatModule : public Module if (settings->Action == ChannelSettings::ACT_BAN) { Modes::ChangeList changelist; - changelist.push_add(ServerInstance->Modes->FindMode('b', MODETYPE_CHANNEL), "*!*@" + user->GetDisplayedHost()); + changelist.push_add(*banmode, "*!*@" + user->GetDisplayedHost()); ServerInstance->Modes->Process(ServerInstance->FakeClient, chan, NULL, changelist); } -- cgit v1.3.1-10-gc9f91 From 5ccf421cbf57a0efaf186df4fb0ec12bcb6e2e09 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Tue, 16 Nov 2021 19:41:16 +0000 Subject: Use a mode reference in the timedbans module. --- src/modules/m_timedbans.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/modules/m_timedbans.cpp b/src/modules/m_timedbans.cpp index 5743088f8..b1432270c 100644 --- a/src/modules/m_timedbans.cpp +++ b/src/modules/m_timedbans.cpp @@ -213,12 +213,15 @@ class ChannelMatcher class ModuleTimedBans : public Module { + private: + ChanModeReference banmode; CommandTban cmd; BanWatcher banwatcher; public: ModuleTimedBans() - : cmd(this) + : banmode(this, "ban") + , cmd(this) , banwatcher(this) { } @@ -260,7 +263,7 @@ class ModuleTimedBans : public Module } Modes::ChangeList setban; - setban.push_remove(ServerInstance->Modes->FindMode('b', MODETYPE_CHANNEL), mask); + setban.push_remove(*banmode, mask); ServerInstance->Modes->Process(ServerInstance->FakeClient, cr, NULL, setban); } } -- cgit v1.3.1-10-gc9f91 From ce88f60a55984ff9456ea826bab1379758e092cf Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Tue, 16 Nov 2021 19:45:10 +0000 Subject: Fix the SSLINFO helpop not describing SSLINFO on channels. --- docs/conf/helpop.conf.example | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/conf/helpop.conf.example b/docs/conf/helpop.conf.example index bfd9012df..e05da8cff 100644 --- a/docs/conf/helpop.conf.example +++ b/docs/conf/helpop.conf.example @@ -53,9 +53,12 @@ match against the nickname of the network service and the oper type of the network service. "> - [0]->{description}; my $docraw = $docdata->[0]->{description} =~ s/^(?:This module )//r; - my $docrendered = markdown ucfirst $docraw, extensions => HOEDOWN_HTML_SKIP_HTML; + my $docrendered = CommonMark->markdown_to_html(ucfirst $docraw); my $docplain = HTML::FormatText->new(leftmargin => 0, rightmargin => ~0)->format(HTML::TreeBuilder->new->parse($docrendered)); my $description = (split_sentences $docplain)[0] =~ s/"/\\"/gr; -- cgit v1.3.1-10-gc9f91 From 16e5f4889ffbc1c4febd954996c304f5db0ac0cd Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Sun, 21 Nov 2021 08:23:37 +0000 Subject: Switch mkdescriptions from YAML::Tiny to YAML. --- tools/mkdescriptions | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/mkdescriptions b/tools/mkdescriptions index c14471edf..056fa64e7 100755 --- a/tools/mkdescriptions +++ b/tools/mkdescriptions @@ -29,7 +29,7 @@ use FindBin qw($RealDir); use HTML::FormatText (); use HTML::TreeBuilder (); use Text::Sentence qw(split_sentences); -use YAML::Tiny (); +use YAML qw(LoadFile); use lib dirname $RealDir; use make::common; @@ -50,10 +50,10 @@ for my $module (<$root/src/modules/extra/m_*.cpp>, <$root/src/modules/m_*.cpp>, my $docfile = catfile $docdir, "$1.yml"; print_error "unable to find the module documentation at $docfile!" unless -f $docfile; - my $docdata = YAML::Tiny->read($docfile) or print_error "unable to read from $docfile: $!"; - print_error "unable to find the module description in $docfile!" unless $docdata->[0]->{description}; + my ($docdata, undef, undef) = LoadFile($docfile) or print_error "unable to read from $docfile: $!"; + print_error "unable to find the module description in $docfile!" unless $docdata->{description}; - my $docraw = $docdata->[0]->{description} =~ s/^(?:This module )//r; + my $docraw = $docdata->{description} =~ s/^(?:This module )//r; my $docrendered = CommonMark->markdown_to_html(ucfirst $docraw); my $docplain = HTML::FormatText->new(leftmargin => 0, rightmargin => ~0)->format(HTML::TreeBuilder->new->parse($docrendered)); -- cgit v1.3.1-10-gc9f91 From f776f9237193dedb3140468a25f38df11c79c6a4 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Fri, 19 Nov 2021 18:28:12 +0000 Subject: Add the option. --- docs/conf/providers/irccloud.conf.example | 3 ++- include/users.h | 3 +++ src/configreader.cpp | 1 + src/users.cpp | 2 ++ 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/conf/providers/irccloud.conf.example b/docs/conf/providers/irccloud.conf.example index 92358c8b6..4fbe3da90 100644 --- a/docs/conf/providers/irccloud.conf.example +++ b/docs/conf/providers/irccloud.conf.example @@ -13,7 +13,8 @@ + allow="5.254.36.56/29 192.184.8.103 192.184.9.108 192.184.9.112 192.184.10.118 192.184.10.9" + uniqueusername="yes"> # This is not typically needed as each user has their own IPv6 but if you have # set to a value lower than 128 you will need to enable it. diff --git a/include/users.h b/include/users.h index 03e3afacc..2079cf773 100644 --- a/include/users.h +++ b/include/users.h @@ -108,6 +108,9 @@ class CoreExport ConnectClass : public refcountbase /** Whether the DNS hostnames of users in this class should be resolved. */ bool resolvehostnames:1; + /** Whether this class is for a shared host where the username (ident) uniquely identifies users. */ + bool uniqueusername:1; + /** The maximum number of channels that users in this class can join. */ unsigned int maxchans; diff --git a/src/configreader.cpp b/src/configreader.cpp index a739bf5b5..5bc15bd41 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -294,6 +294,7 @@ void ServerConfig::CrossCheckConnectBlocks(ServerConfig* current) me->maxconnwarn = tag->getBool("maxconnwarn", me->maxconnwarn); me->limit = tag->getUInt("limit", me->limit); me->resolvehostnames = tag->getBool("resolvehostnames", me->resolvehostnames); + me->uniqueusername = tag->getBool("uniqueusername", me->uniqueusername); me->password = tag->getString("password", me->password); me->passwordhash = tag->getString("hash", me->passwordhash); diff --git a/src/users.cpp b/src/users.cpp index 1ec7d9423..6d8766082 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -1265,6 +1265,7 @@ ConnectClass::ConnectClass(ConfigTag* tag, char t, const std::string& mask) , fakelag(true) , maxconnwarn(true) , resolvehostnames(true) + , uniqueusername(false) , maxchans(0) , penaltythreshold(0) , pingtime(0) @@ -1332,6 +1333,7 @@ void ConnectClass::Update(const ConnectClass* src) fakelag = src->fakelag; maxconnwarn = src->maxconnwarn; resolvehostnames = src->resolvehostnames; + uniqueusername = src->uniqueusername; maxchans = src->maxchans; penaltythreshold = src->penaltythreshold; pingtime = src->pingtime; -- cgit v1.3.1-10-gc9f91 From 303c7926071b14f684a80d5502d3e1ebaa47ca11 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Tue, 23 Nov 2021 23:04:08 +0000 Subject: Remind users about the `selfsigned` option to inspircd-testssl. --- tools/testssl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/testssl b/tools/testssl index 9a08e31a5..c64dbf5f0 100755 --- a/tools/testssl +++ b/tools/testssl @@ -143,8 +143,10 @@ ${\CC_RED}no${\CC_RESET} It appears that something is wrong with your server. Make sure that: - - You are not using an old version of GnuTLS, mbedTLS, or OpenSSL which only + * You are not using an old version of GnuTLS, mbedTLS, or OpenSSL which only supports deprecated algorithms like SSLv3. + * If you are using a self-signed certificate (not recommended) that you passed + the `selfsigned` argument to this script. The error provided by the SSL library was: -- cgit v1.3.1-10-gc9f91 From 1953470737263fc16c4f92cc9e69bcf130d90571 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Wed, 24 Nov 2021 04:58:46 +0000 Subject: Escape the real and displayed hostnames in httpd_stats. --- src/modules/m_httpd_stats.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/m_httpd_stats.cpp b/src/modules/m_httpd_stats.cpp index 55cd6e23f..58bf32ee9 100644 --- a/src/modules/m_httpd_stats.cpp +++ b/src/modules/m_httpd_stats.cpp @@ -216,7 +216,7 @@ namespace Stats { data << ""; data << "" << u->nick << "" << u->uuid << "" - << u->GetRealHost() << "" << u->GetDisplayedHost() << "" + << Sanitize(u->GetRealHost()) << "" << Sanitize(u->GetDisplayedHost()) << "" << Sanitize(u->GetRealName()) << "" << u->server->GetName() << "" << u->signon << "" << u->age << ""; -- cgit v1.3.1-10-gc9f91 From 167df45be9ccc4cb0569c818fb6e86d394ffc2d6 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Wed, 24 Nov 2021 05:57:55 +0000 Subject: Escape the IP address in httpd_stats. --- src/modules/m_httpd_stats.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/m_httpd_stats.cpp b/src/modules/m_httpd_stats.cpp index 58bf32ee9..9c6454c5a 100644 --- a/src/modules/m_httpd_stats.cpp +++ b/src/modules/m_httpd_stats.cpp @@ -235,7 +235,7 @@ namespace Stats << lu->GetClass()->GetName() << "" << lu->idle_lastmsg << ""; - data << "" << u->GetIPString() << ""; + data << "" << Sanitize(u->GetIPString()) << ""; DumpMeta(data, u); -- cgit v1.3.1-10-gc9f91 From 047473426bc6e60185c2576ec3f585b9e62d5072 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Wed, 24 Nov 2021 06:00:12 +0000 Subject: Make parsing websocket proxy headers more robust. --- src/modules/m_websocket.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/modules/m_websocket.cpp b/src/modules/m_websocket.cpp index c70fd2c73..0b43ea60b 100644 --- a/src/modules/m_websocket.cpp +++ b/src/modules/m_websocket.cpp @@ -384,15 +384,23 @@ class WebSocketHook : public IOHookMiddle irc::sockets::sockaddrs realsa(luser->client_sa); HTTPHeaderFinder proxyheader; - if (proxyheader.Find(recvq, "X-Real-IP:", 10, reqend) - && irc::sockets::aptosa(proxyheader.ExtractValue(recvq), realsa.port(), realsa)) + if (proxyheader.Find(recvq, "X-Real-IP:", 10, reqend) || proxyheader.Find(recvq, "X-Forwarded-For:", 16, reqend)) { - // Nothing to do here. + // Attempt to parse the proxy HTTP header. + irc::sockets::aptosa(proxyheader.ExtractValue(recvq), realsa.port(), realsa); } - else if (proxyheader.Find(recvq, "X-Forwarded-For:", 16, reqend) - && irc::sockets::aptosa(proxyheader.ExtractValue(recvq), realsa.port(), realsa)) + else { - // Nothing to do here. + // The proxy header is missing. + FailHandshake(sock, "HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n", "WebSocket: Received a proxied HTTP request that did not send a real IP address header"); + return -1; + } + + if (realsa.family() == AF_UNSPEC) + { + // The proxy header value contains a malformed value. + FailHandshake(sock, "HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n", "WebSocket: Received a proxied HTTP request that sent a malformed real IP address"); + return -1; } for (WebSocketConfig::ProxyRanges::const_iterator iter = config.proxyranges.begin(); iter != config.proxyranges.end(); ++iter) -- cgit v1.3.1-10-gc9f91