diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/command_parse.cpp | 17 | ||||
-rw-r--r-- | src/commands/cmd_motd.cpp | 6 | ||||
-rw-r--r-- | src/commands/cmd_pass.cpp | 1 | ||||
-rw-r--r-- | src/commands/cmd_ping.cpp | 2 | ||||
-rw-r--r-- | src/commands/cmd_pong.cpp | 11 | ||||
-rw-r--r-- | src/commands/cmd_rules.cpp | 6 | ||||
-rw-r--r-- | src/commands/cmd_stats.cpp | 6 | ||||
-rw-r--r-- | src/commands/cmd_user.cpp | 1 |
8 files changed, 46 insertions, 4 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; } diff --git a/src/commands/cmd_motd.cpp b/src/commands/cmd_motd.cpp index 869a9c353..9ed5ff188 100644 --- a/src/commands/cmd_motd.cpp +++ b/src/commands/cmd_motd.cpp @@ -51,7 +51,13 @@ class CommandMotd : public Command CmdResult CommandMotd::Handle (const std::vector<std::string>& parameters, User *user) { if (parameters.size() > 0 && parameters[0] != ServerInstance->Config->ServerName) + { + // Give extra penalty if a non-oper queries the /MOTD of a remote server + LocalUser* localuser = IS_LOCAL(user); + if ((localuser) && (!IS_OPER(user))) + localuser->CommandFloodPenalty += 2000; return CMD_SUCCESS; + } ConfigTag* tag = ServerInstance->Config->EmptyTag; if (IS_LOCAL(user)) diff --git a/src/commands/cmd_pass.cpp b/src/commands/cmd_pass.cpp index f082a4ce8..9fc758874 100644 --- a/src/commands/cmd_pass.cpp +++ b/src/commands/cmd_pass.cpp @@ -46,6 +46,7 @@ CmdResult CommandPass::HandleLocal(const std::vector<std::string>& parameters, L // Check to make sure they haven't registered -- Fix by FCS if (user->registered == REG_ALL) { + user->CommandFloodPenalty += 1000; user->WriteNumeric(ERR_ALREADYREGISTERED, "%s :You may not reregister",user->nick.c_str()); return CMD_FAILURE; } diff --git a/src/commands/cmd_ping.cpp b/src/commands/cmd_ping.cpp index 3ccadd929..dd14b52c8 100644 --- a/src/commands/cmd_ping.cpp +++ b/src/commands/cmd_ping.cpp @@ -30,7 +30,7 @@ class CommandPing : public Command public: /** Constructor for ping. */ - CommandPing ( Module* parent) : Command(parent,"PING", 1, 2) { Penalty = 0; syntax = "<servername> [:<servername>]"; } + CommandPing ( Module* parent) : Command(parent,"PING", 1, 2) { syntax = "<servername> [:<servername>]"; } /** Handle command. * @param parameters The parameters to the comamnd * @param pcnt The number of parameters passed to teh command diff --git a/src/commands/cmd_pong.cpp b/src/commands/cmd_pong.cpp index 825168de7..3b6f17f3b 100644 --- a/src/commands/cmd_pong.cpp +++ b/src/commands/cmd_pong.cpp @@ -43,8 +43,15 @@ class CommandPong : public Command CmdResult CommandPong::Handle (const std::vector<std::string>&, User *user) { // set the user as alive so they survive to next ping - if (IS_LOCAL(user)) - IS_LOCAL(user)->lastping = 1; + LocalUser* localuser = IS_LOCAL(user); + if (localuser) + { + // Increase penalty unless we've sent a PING and this is the reply + if (localuser->lastping) + localuser->CommandFloodPenalty += 1000; + else + localuser->lastping = 1; + } return CMD_SUCCESS; } diff --git a/src/commands/cmd_rules.cpp b/src/commands/cmd_rules.cpp index 17de9f3f2..7aacf8c31 100644 --- a/src/commands/cmd_rules.cpp +++ b/src/commands/cmd_rules.cpp @@ -49,7 +49,13 @@ class CommandRules : public Command CmdResult CommandRules::Handle (const std::vector<std::string>& parameters, User *user) { if (parameters.size() > 0 && parameters[0] != ServerInstance->Config->ServerName) + { + // Give extra penalty if a non-oper queries the /RULES of a remote server + LocalUser* localuser = IS_LOCAL(user); + if ((localuser) && (!IS_OPER(user))) + localuser->CommandFloodPenalty += 2000; return CMD_SUCCESS; + } ConfigTag* tag = ServerInstance->Config->EmptyTag; if (IS_LOCAL(user)) diff --git a/src/commands/cmd_stats.cpp b/src/commands/cmd_stats.cpp index 60bb5b30e..d547635ed 100644 --- a/src/commands/cmd_stats.cpp +++ b/src/commands/cmd_stats.cpp @@ -420,7 +420,13 @@ void CommandStats::DoStats(char statschar, User* user, string_list &results) CmdResult CommandStats::Handle (const std::vector<std::string>& parameters, User *user) { if (parameters.size() > 1 && parameters[1] != ServerInstance->Config->ServerName) + { + // Give extra penalty if a non-oper does /STATS <remoteserver> + LocalUser* localuser = IS_LOCAL(user); + if ((localuser) && (!IS_OPER(user))) + localuser->CommandFloodPenalty += 2000; return CMD_SUCCESS; + } string_list values; char search = parameters[0][0]; DoStats(search, user, values); diff --git a/src/commands/cmd_user.cpp b/src/commands/cmd_user.cpp index 305d0847f..09e1e3319 100644 --- a/src/commands/cmd_user.cpp +++ b/src/commands/cmd_user.cpp @@ -68,6 +68,7 @@ CmdResult CommandUser::HandleLocal(const std::vector<std::string>& parameters, L } else { + user->CommandFloodPenalty += 1000; user->WriteNumeric(462, "%s :You may not reregister", user->nick.c_str()); return CMD_FAILURE; } |