summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAttila Molnar <attilamolnar@hush.com>2015-01-12 14:24:23 +0100
committerAttila Molnar <attilamolnar@hush.com>2015-01-12 14:24:23 +0100
commit80350a67aa7d45e5068f46b8995be92b0d9b40aa (patch)
treeb311a9b3817952ef2082a2b105710c291c430f54
parent83bcc83a56a235f5c4e479ff47713f467640a4eb (diff)
Always penalize clients executing a command which fails before running the handler, even if the command has 0 penalty
-rw-r--r--src/command_parse.cpp17
1 files changed, 16 insertions, 1 deletions
diff --git a/src/command_parse.cpp b/src/command_parse.cpp
index 1c72c7de4..0dd793592 100644
--- a/src/command_parse.cpp
+++ b/src/command_parse.cpp
@@ -204,12 +204,22 @@ bool CommandParser::ProcessCommand(LocalUser *user, std::string &cmd)
/* find the command, check it exists */
Commandtable::iterator cm = cmdlist.find(command);
+ // Penalty to give if the command fails before the handler is executed
+ unsigned int failpenalty = 0;
+
/* Modify the user's penalty regardless of whether or not the command exists */
bool do_more = true;
if (!user->HasPrivPermission("users/flood/no-throttle"))
{
// If it *doesn't* exist, give it a slightly heftier penalty than normal to deter flooding us crap
- user->CommandFloodPenalty += cm != cmdlist.end() ? cm->second->Penalty * 1000 : 2000;
+ unsigned int penalty = (cm != cmdlist.end() ? cm->second->Penalty * 1000 : 2000);
+ user->CommandFloodPenalty += penalty;
+
+ // Increase their penalty later if we fail and the command has 0 penalty by default (i.e. in Command::Penalty) to
+ // throttle sending ERR_* from the command parser. If the command does have a non-zero penalty then this is not
+ // needed because we've increased their penalty above.
+ if (penalty == 0)
+ failpenalty = 1000;
}
@@ -290,11 +300,13 @@ bool CommandParser::ProcessCommand(LocalUser *user, std::string &cmd)
{
if (!user->IsModeSet(cm->second->flags_needed))
{
+ user->CommandFloodPenalty += failpenalty;
user->WriteNumeric(ERR_NOPRIVILEGES, "%s :Permission Denied - You do not have the required operator privileges",user->nick.c_str());
return do_more;
}
if (!user->HasPermission(command))
{
+ user->CommandFloodPenalty += failpenalty;
user->WriteNumeric(ERR_NOPRIVILEGES, "%s :Permission Denied - Oper type %s does not have access to command %s",
user->nick.c_str(), user->oper->NameStr(), command.c_str());
return do_more;
@@ -303,6 +315,7 @@ bool CommandParser::ProcessCommand(LocalUser *user, std::string &cmd)
if ((user->registered == REG_ALL) && (!IS_OPER(user)) && (cm->second->IsDisabled()))
{
/* command is disabled! */
+ user->CommandFloodPenalty += failpenalty;
if (ServerInstance->Config->DisabledDontExist)
{
user->WriteNumeric(ERR_UNKNOWNCOMMAND, "%s %s :Unknown command",user->nick.c_str(),command.c_str());
@@ -323,6 +336,7 @@ bool CommandParser::ProcessCommand(LocalUser *user, std::string &cmd)
if (command_p.size() < cm->second->min_params)
{
+ user->CommandFloodPenalty += failpenalty;
user->WriteNumeric(ERR_NEEDMOREPARAMS, "%s %s :Not enough parameters.", user->nick.c_str(), command.c_str());
if ((ServerInstance->Config->SyntaxHints) && (user->registered == REG_ALL) && (cm->second->syntax.length()))
user->WriteNumeric(RPL_SYNTAX, "%s :SYNTAX %s %s", user->nick.c_str(), cm->second->name.c_str(), cm->second->syntax.c_str());
@@ -330,6 +344,7 @@ bool CommandParser::ProcessCommand(LocalUser *user, std::string &cmd)
}
if ((user->registered != REG_ALL) && (!cm->second->WorksBeforeReg()))
{
+ user->CommandFloodPenalty += failpenalty;
user->WriteNumeric(ERR_NOTREGISTERED, "%s :You have not registered",command.c_str());
return do_more;
}