X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fcommand_parse.cpp;h=7998d9cc3a982f0f71732a2f7dfe4af2b831e9f3;hb=63aa8d0d42f619c52d382bde3e6ba2e5e23b12ac;hp=7133b3f053110347f9a9b2d30debd207e73b683c;hpb=3fef0ed889eecb40b96a597924254560c81d4a09;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/command_parse.cpp b/src/command_parse.cpp index 7133b3f05..7998d9cc3 100644 --- a/src/command_parse.cpp +++ b/src/command_parse.cpp @@ -40,7 +40,7 @@ bool InspIRCd::PassCompare(Extensible* ex, const std::string& data, const std::s if (!hashtype.empty() && hashtype != "plaintext") return false; - return (data == input); + return TimingSafeCompare(data, input); } bool CommandParser::LoopCall(User* user, Command* handler, const std::vector& parameters, unsigned int splithere, int extra, bool usemax) @@ -60,7 +60,7 @@ bool CommandParser::LoopCall(User* user, Command* handler, const std::vector dupes; + insp::flat_set dupes; bool check_dupes = (extra < 0); /* Create two sepstreams, if we have only one list, then initialize the second sepstream with @@ -109,7 +109,7 @@ bool CommandParser::LoopCall(User* user, Command* handler, const std::vectorsecond; @@ -120,7 +120,7 @@ Command* CommandParser::GetHandler(const std::string &commandname) CmdResult CommandParser::CallHandler(const std::string& commandname, const std::vector& parameters, User* user, Command** cmd) { - Commandtable::iterator n = cmdlist.find(commandname); + CommandMap::iterator n = cmdlist.find(commandname); if (n != cmdlist.end()) { @@ -182,11 +182,21 @@ void CommandParser::ProcessCommand(LocalUser *user, std::string &cmd) /* find the command, check it exists */ Command* handler = GetHandler(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 */ 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 += handler ? handler->Penalty * 1000 : 2000; + unsigned int penalty = (handler ? handler->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; } if (!handler) @@ -208,7 +218,7 @@ void CommandParser::ProcessCommand(LocalUser *user, std::string &cmd) { if (user->registered == REG_ALL) user->WriteNumeric(ERR_UNKNOWNCOMMAND, "%s :Unknown command",command.c_str()); - ServerInstance->stats->statsUnknown++; + ServerInstance->stats.Unknown++; return; } } @@ -257,12 +267,14 @@ void CommandParser::ProcessCommand(LocalUser *user, std::string &cmd) { if (!user->IsModeSet(handler->flags_needed)) { + user->CommandFloodPenalty += failpenalty; user->WriteNumeric(ERR_NOPRIVILEGES, ":Permission Denied - You do not have the required operator privileges"); return; } if (!user->HasPermission(command)) { + user->CommandFloodPenalty += failpenalty; user->WriteNumeric(ERR_NOPRIVILEGES, ":Permission Denied - Oper type %s does not have access to command %s", user->oper->name.c_str(), command.c_str()); return; @@ -272,6 +284,7 @@ void CommandParser::ProcessCommand(LocalUser *user, std::string &cmd) if ((user->registered == REG_ALL) && (!user->IsOper()) && (handler->IsDisabled())) { /* command is disabled! */ + user->CommandFloodPenalty += failpenalty; if (ServerInstance->Config->DisabledDontExist) { user->WriteNumeric(ERR_UNKNOWNCOMMAND, "%s :Unknown command", command.c_str()); @@ -281,7 +294,7 @@ void CommandParser::ProcessCommand(LocalUser *user, std::string &cmd) user->WriteNumeric(ERR_UNKNOWNCOMMAND, "%s :This command has been disabled.", command.c_str()); } - ServerInstance->SNO->WriteToSnoMask('t', "%s denied for %s (%s@%s)", + ServerInstance->SNO->WriteToSnoMask('a', "%s denied for %s (%s@%s)", command.c_str(), user->nick.c_str(), user->ident.c_str(), user->host.c_str()); return; } @@ -291,6 +304,7 @@ void CommandParser::ProcessCommand(LocalUser *user, std::string &cmd) if (command_p.size() < handler->min_params) { + user->CommandFloodPenalty += failpenalty; user->WriteNumeric(ERR_NEEDMOREPARAMS, "%s :Not enough parameters.", command.c_str()); if ((ServerInstance->Config->SyntaxHints) && (user->registered == REG_ALL) && (handler->syntax.length())) user->WriteNumeric(RPL_SYNTAX, ":SYNTAX %s %s", handler->name.c_str(), handler->syntax.c_str()); @@ -299,6 +313,7 @@ void CommandParser::ProcessCommand(LocalUser *user, std::string &cmd) if ((user->registered != REG_ALL) && (!handler->WorksBeforeReg())) { + user->CommandFloodPenalty += failpenalty; user->WriteNumeric(ERR_NOTREGISTERED, "%s :You have not registered",command.c_str()); } else @@ -322,18 +337,46 @@ void CommandParser::ProcessCommand(LocalUser *user, std::string &cmd) void CommandParser::RemoveCommand(Command* x) { - Commandtable::iterator n = cmdlist.find(x->name); + CommandMap::iterator n = cmdlist.find(x->name); if (n != cmdlist.end() && n->second == x) cmdlist.erase(n); } +CommandBase::CommandBase(Module* mod, const std::string& cmd, unsigned int minpara, unsigned int maxpara) + : ServiceProvider(mod, cmd, SERVICE_COMMAND) + , flags_needed(0) + , min_params(minpara) + , max_params(maxpara) + , use_count(0) + , disabled(false) + , works_before_reg(false) + , allow_empty_last_param(true) + , Penalty(1) +{ +} + CommandBase::~CommandBase() { } +void CommandBase::EncodeParameter(std::string& parameter, int index) +{ +} + +RouteDescriptor CommandBase::GetRouting(User* user, const std::vector& parameters) +{ + return ROUTE_LOCALONLY; +} + +Command::Command(Module* mod, const std::string& cmd, unsigned int minpara, unsigned int maxpara) + : CommandBase(mod, cmd, minpara, maxpara) + , force_manual_route(false) +{ +} + Command::~Command() { - ServerInstance->Parser->RemoveCommand(this); + ServerInstance->Parser.RemoveCommand(this); } void CommandParser::ProcessBuffer(std::string &buffer,LocalUser *user)