Allow hiding small channels from /LIST past the securelist wait time.

This commit is contained in:
Sadie Powell 2023-07-09 17:13:13 +01:00
parent d84a041601
commit de72202cb3
2 changed files with 30 additions and 3 deletions

View File

@ -2183,8 +2183,9 @@
# requiressl="yes"> # requiressl="yes">
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
# Secure list module: Prevent /LIST in the first minute of connection, # Secure list module: Prevent users from using the /LIST command until
# crippling most spambots and trojan spreader bots. # a predefined period has passed. This helps protect your network from
# spambots.
#<module name="securelist"> #<module name="securelist">
# #
#-#-#-#-#-#-#-#-#-# SECURELIST CONFIGURATION -#-#-#-#-#-#-#-#-#-#-#-#-# #-#-#-#-#-#-#-#-#-# SECURELIST CONFIGURATION -#-#-#-#-#-#-#-#-#-#-#-#-#
@ -2207,6 +2208,11 @@
# fakechantopic - The topic for the fake channels. A random format # # fakechantopic - The topic for the fake channels. A random format #
# modifier will be inserted into this for randomness. # # modifier will be inserted into this for randomness. #
# # # #
# hidesmallchans - The minimum user count for a channel to show up in #
# /LIST after the wait period (see below). If a user #
# is exempt from the wait period this will not apply #
# to them. #
# #
# showmsg - Whether to tell users that they need to wait for a while # # showmsg - Whether to tell users that they need to wait for a while #
# before they can use the /LIST command. # # before they can use the /LIST command. #
# Defaults to no. # # Defaults to no. #
@ -2219,6 +2225,7 @@
# fakechans="5" # fakechans="5"
# fakechanprefix="#spam" # fakechanprefix="#spam"
# fakechantopic="Fake channel for confusing spambots" # fakechantopic="Fake channel for confusing spambots"
# hidesmallchans="0"
# showmsg="yes" # showmsg="yes"
# waittime="1m"> # waittime="1m">

View File

@ -42,10 +42,12 @@ private:
unsigned long fakechans; unsigned long fakechans;
std::string fakechanprefix; std::string fakechanprefix;
std::string fakechantopic; std::string fakechantopic;
size_t hidesmallchans;
bool sendingfakelist = false;
bool showmsg; bool showmsg;
unsigned long waittime; unsigned long waittime;
bool IsExempt(LocalUser* user) bool IsExempt(User* user)
{ {
// Allow if the source is a privileged server operator. // Allow if the source is a privileged server operator.
if (user->HasPrivPermission("servers/ignore-securelist")) if (user->HasPrivPermission("servers/ignore-securelist"))
@ -94,6 +96,7 @@ public:
fakechans = tag->getNum<unsigned long>("fakechans", 5, 0); fakechans = tag->getNum<unsigned long>("fakechans", 5, 0);
fakechanprefix = tag->getString("fakechanprefix", "#", 1, ServerInstance->Config->Limits.MaxChannel - 1); fakechanprefix = tag->getString("fakechanprefix", "#", 1, ServerInstance->Config->Limits.MaxChannel - 1);
fakechantopic = tag->getString("fakechantopic", "Fake channel for confusing spambots", 1, ServerInstance->Config->Limits.MaxTopic - 1); fakechantopic = tag->getString("fakechantopic", "Fake channel for confusing spambots", 1, ServerInstance->Config->Limits.MaxTopic - 1);
hidesmallchans = tag->getNum<size_t>("hidesmallchans", 0);
showmsg = tag->getBool("showmsg", true); showmsg = tag->getBool("showmsg", true);
waittime = tag->getDuration("waittime", 60, 1, 60*60*24); waittime = tag->getDuration("waittime", 60, 1, 60*60*24);
@ -122,6 +125,8 @@ public:
// The client might be waiting on a response to do something so send them an // The client might be waiting on a response to do something so send them an
// fake list response to satisfy that. // fake list response to satisfy that.
size_t maxfakesuffix = ServerInstance->Config->Limits.MaxChannel - fakechanprefix.size(); size_t maxfakesuffix = ServerInstance->Config->Limits.MaxChannel - fakechanprefix.size();
sendingfakelist = true;
user->WriteNumeric(RPL_LISTSTART, "Channel", "Users Name"); user->WriteNumeric(RPL_LISTSTART, "Channel", "Users Name");
for (unsigned long fakechan = 0; fakechan < fakechans; ++fakechan) for (unsigned long fakechan = 0; fakechan < fakechans; ++fakechan)
{ {
@ -140,9 +145,24 @@ public:
user->WriteNumeric(RPL_LIST, fakechanprefix + chansuffix, chanusers, chantopic); user->WriteNumeric(RPL_LIST, fakechanprefix + chansuffix, chanusers, chantopic);
} }
user->WriteNumeric(RPL_LISTEND, "End of channel list."); user->WriteNumeric(RPL_LISTEND, "End of channel list.");
sendingfakelist = false;
return MOD_RES_DENY; return MOD_RES_DENY;
} }
ModResult OnNumeric(User* user, const Numeric::Numeric& numeric) override
{
if (numeric.GetNumeric() != RPL_LIST || numeric.GetParams().size() < 2)
return MOD_RES_PASSTHRU; // The numeric isn't the one we care about.
if (sendingfakelist || IsExempt(user))
return MOD_RES_PASSTHRU; // This numeric should be shown even if too small.
// If the channel has less than the minimum amount of users then hide it from /LIST.
auto usercount = ConvToNum<size_t>(numeric.GetParams()[1]);
return usercount < hidesmallchans ? MOD_RES_DENY : MOD_RES_PASSTHRU;
}
void OnBuildISupport(ISupport::TokenMap& tokens) override void OnBuildISupport(ISupport::TokenMap& tokens) override
{ {
if (showmsg) if (showmsg)