* Copyright (C) 2019 Matt Schatz <genius3000@g3k.solutions>
* Copyright (C) 2018 linuxdaemon <linuxdaemon.irc@gmail.com>
* Copyright (C) 2017-2018 B00mX0r <b00mx0r@aureus.pw>
- * Copyright (C) 2013, 2017-2018, 2020 Sadie Powell <sadie@witchery.services>
- * Copyright (C) 2012-2016 Attila Molnar <attilamolnar@hush.com>
- * Copyright (C) 2012, 2018-2019 Robby <robby@chatbelgie.be>
+ * Copyright (C) 2013, 2017-2018, 2020-2021 Sadie Powell <sadie@witchery.services>
+ * Copyright (C) 2012-2013, 2015-2016 Attila Molnar <attilamolnar@hush.com>
+ * Copyright (C) 2012, 2019 Robby <robby@chatbelgie.be>
* Copyright (C) 2012 Jens Voss <DukePyrolator@anope.org>
* Copyright (C) 2009 Uli Schlachter <psychon@inspircd.org>
- * Copyright (C) 2009 Matt Smith <dz@inspircd.org>
- * Copyright (C) 2009 John Brooks <special@inspircd.org>
* Copyright (C) 2009 Dennis Friis <peavey@inspircd.org>
* Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
* Copyright (C) 2008-2010 Craig Edwards <brain@inspircd.org>
- * Copyright (C) 2008-2009 Robin Burchell <robin+git@viroteck.net>
* Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
+ * Copyright (C) 2008 Robin Burchell <robin+git@viroteck.net>
*
* 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
}
};
-//typedef std::vector<Shun> shunlist;
-
class CommandShun : public Command
{
public:
CommandShun(Module* Creator) : Command(Creator, "SHUN", 1, 3)
{
- flags_needed = 'o'; this->syntax = "<nick!user@host> [<duration> :<reason>]";
+ flags_needed = 'o';
+ syntax = "<nick!user@host> [<duration> :<reason>]";
}
CmdResult Handle(User* user, const Params& parameters) CXX11_OVERRIDE
class ModuleShun : public Module, public Stats::EventListener
{
+ private:
CommandShun cmd;
- ShunFactory f;
- insp::flat_set<std::string> ShunEnabledCommands;
- bool NotifyOfShun;
+ ShunFactory shun;
+ insp::flat_set<std::string, irc::insensitive_swo> cleanedcommands;
+ insp::flat_set<std::string, irc::insensitive_swo> enabledcommands;
bool affectopers;
+ bool allowconnect;
+ bool allowtags;
+ bool notifyuser;
+
+ bool IsShunned(LocalUser* user)
+ {
+ // Exempt the user if they are not fully connected and allowconnect is enabled.
+ if (allowconnect && user->registered != REG_ALL)
+ return false;
+
+ // Exempt the user from shuns if they are an oper and affectopers is disabled.
+ if (!affectopers && user->IsOper())
+ return false;
+
+ // Exempt the user from shuns if they are an oper with the servers/ignore-shun privilege.
+ if (user->HasPrivPermission("servers/ignore-shun"))
+ return false;
+
+ // Check whether the user is actually shunned.
+ return ServerInstance->XLines->MatchesLine("SHUN", user);
+ }
public:
ModuleShun()
void init() CXX11_OVERRIDE
{
- ServerInstance->XLines->RegisterFactory(&f);
+ ServerInstance->XLines->RegisterFactory(&shun);
}
~ModuleShun()
{
ServerInstance->XLines->DelAll("SHUN");
- ServerInstance->XLines->UnregisterFactory(&f);
+ ServerInstance->XLines->UnregisterFactory(&shun);
}
void Prioritize() CXX11_OVERRIDE
{
ConfigTag* tag = ServerInstance->Config->ConfValue("shun");
- ShunEnabledCommands.clear();
+ cleanedcommands.clear();
+ irc::spacesepstream cleanedcmds(tag->getString("cleanedcommands", "AWAY PART QUIT"));
+ for (std::string cleanedcmd; cleanedcmds.GetToken(cleanedcmd); )
+ cleanedcommands.insert(cleanedcmd);
+
+ enabledcommands.clear();
irc::spacesepstream enabledcmds(tag->getString("enabledcommands", "ADMIN OPER PING PONG QUIT", 1));
for (std::string enabledcmd; enabledcmds.GetToken(enabledcmd); )
- {
- std::transform(enabledcmd.begin(), enabledcmd.end(), enabledcmd.begin(), ::toupper);
- ShunEnabledCommands.insert(enabledcmd);
- }
+ enabledcommands.insert(enabledcmd);
- NotifyOfShun = tag->getBool("notifyuser", true);
affectopers = tag->getBool("affectopers", false);
+ allowtags = tag->getBool("allowtags");
+ allowconnect = tag->getBool("allowconnect");
+ notifyuser = tag->getBool("notifyuser", true);
}
ModResult OnPreCommand(std::string& command, CommandBase::Params& parameters, LocalUser* user, bool validated) CXX11_OVERRIDE
{
- if (validated)
+ if (validated || !IsShunned(user))
return MOD_RES_PASSTHRU;
- // Exempt the user from shuns if:
- // (1) They are an oper and affectopers is disabled.
- // (2) They have the servers/ignore-shun privilege.
- if ((!affectopers && user->IsOper()) || user->HasPrivPermission("servers/ignore-shun"))
- return MOD_RES_PASSTHRU;
-
- if (ServerInstance->XLines->MatchesLine("SHUN", user) && !ShunEnabledCommands.count(command))
+ if (!enabledcommands.count(command))
{
- if (NotifyOfShun)
- user->WriteNotice("*** Command " + command + " not processed, as you have been blocked from issuing commands (SHUN)");
+ if (notifyuser)
+ user->WriteNotice("*** " + command + " command not processed as you have been blocked from issuing commands.");
return MOD_RES_DENY;
}
- if (command == "QUIT")
+ if (!allowtags)
{
- /* Allow QUIT but dont show any quit message */
- parameters.clear();
+ // Remove all client tags.
+ ClientProtocol::TagMap& tags = parameters.GetTags();
+ for (ClientProtocol::TagMap::iterator tag = tags.begin(); tag != tags.end(); )
+ {
+ if (tag->first[0] == '+')
+ tag = tags.erase(tag);
+ else
+ tag++;
+ }
}
- else if ((command == "PART") && (parameters.size() > 1))
+
+ if (cleanedcommands.count(command))
{
- /* same for PART */
- parameters.pop_back();
+ if (command == "AWAY" && !parameters.empty())
+ {
+ // Allow away but only for unsetting.
+ parameters.clear();
+ }
+ else if (command == "PART" && parameters.size() > 1)
+ {
+ // Allow part but strip the message.
+ parameters.pop_back();
+ }
+ else if (command == "QUIT" && !parameters.empty())
+ {
+ // Allow quit but strip the message.
+ parameters.clear();
+ }
}
- /* if we're here, allow the command. */
return MOD_RES_PASSTHRU;
}