diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/command_parse.cpp | 60 | ||||
-rw-r--r-- | src/hashcomp.cpp | 5 | ||||
-rw-r--r-- | src/modules/m_passforward.cpp | 2 | ||||
-rw-r--r-- | src/users.cpp | 2 |
4 files changed, 42 insertions, 27 deletions
diff --git a/src/command_parse.cpp b/src/command_parse.cpp index fb8ea2565..c133c475e 100644 --- a/src/command_parse.cpp +++ b/src/command_parse.cpp @@ -159,26 +159,8 @@ CmdResult CommandParser::CallHandler(const std::string& commandname, const Comma return CMD_INVALID; } -void CommandParser::ProcessCommand(LocalUser *user, std::string &cmd) +void CommandParser::ProcessCommand(LocalUser* user, std::string& command, Command::Params& command_p) { - CommandBase::Params command_p; - irc::tokenstream tokens(cmd); - std::string command, token; - tokens.GetMiddle(command); - - /* A client sent a nick prefix on their command (ick) - * rhapsody and some braindead bouncers do this -- - * the rfc says they shouldnt but also says the ircd should - * discard it if they do. - */ - if (command[0] == ':') - tokens.GetMiddle(command); - - while (tokens.GetTrailing(token)) - command_p.push_back(token); - - std::transform(command.begin(), command.end(), command.begin(), ::toupper); - /* find the command, check it exists */ Command* handler = GetHandler(command); @@ -385,13 +367,47 @@ void Command::RegisterService() throw ModuleException("Command already exists: " + name); } -void CommandParser::ProcessBuffer(std::string &buffer,LocalUser *user) +void CommandParser::ProcessBuffer(LocalUser* user, const std::string& buffer) { - if (buffer.empty()) + size_t start = buffer.find_first_not_of(" "); + if (start == std::string::npos) + { + // Discourage the user from flooding the server. + user->CommandFloodPenalty += 2000; return; + } ServerInstance->Logs->Log("USERINPUT", LOG_RAWIO, "C[%s] I %s", user->uuid.c_str(), buffer.c_str()); - ProcessCommand(user,buffer); + + irc::tokenstream tokens(buffer, start); + std::string command; + CommandBase::Params parameters; + + // Get the command name. This will always exist because of the check + // at the start of the function. + tokens.GetMiddle(command); + + // If this exists then the client sent a prefix as part of their + // message. Section 2.3 of RFC 1459 technically says we should only + // allow the nick of the client here but in practise everyone just + // ignores it so we will copy them. + if (command[0] == ':' && !tokens.GetMiddle(command)) + { + // Discourage the user from flooding the server. + user->CommandFloodPenalty += 2000; + return; + } + + // We upper-case the command name to ensure consistency internally. + std::transform(command.begin(), command.end(), command.begin(), ::toupper); + + // Build the parameter map. We intentionally do not respect the RFC 1459 + // thirteen parameter limit here. + std::string parameter; + while (tokens.GetTrailing(parameter)) + parameters.push_back(parameter); + + ProcessCommand(user, command, parameters); } bool CommandParser::AddCommand(Command *f) diff --git a/src/hashcomp.cpp b/src/hashcomp.cpp index 47c36b91b..8febcbb5f 100644 --- a/src/hashcomp.cpp +++ b/src/hashcomp.cpp @@ -212,7 +212,7 @@ bool irc::tokenstream::GetMiddle(std::string& token) size_t separator = message.find(' ', position); if (separator == std::string::npos) { - token.assign(message, position); + token.assign(message, position, std::string::npos); position = message.length(); return true; } @@ -234,9 +234,8 @@ bool irc::tokenstream::GetTrailing(std::string& token) // If this is true then we have a <trailing> token! if (message[position] == ':') { - token.assign(message, position + 1); + token.assign(message, position + 1, std::string::npos); position = message.length(); - ServerInstance->Logs->Log("HASHCOMP", LOG_DEBUG, "TRAILING %s next (none)", token.c_str()); return true; } diff --git a/src/modules/m_passforward.cpp b/src/modules/m_passforward.cpp index 3050dba0b..e3f8624fc 100644 --- a/src/modules/m_passforward.cpp +++ b/src/modules/m_passforward.cpp @@ -96,7 +96,7 @@ class ModulePassForward : public Module tmp.clear(); FormatStr(tmp,forwardcmd, user); - ServerInstance->Parser.ProcessBuffer(tmp,user); + ServerInstance->Parser.ProcessBuffer(user, tmp); } }; diff --git a/src/users.cpp b/src/users.cpp index 52e1f3e95..737a3fa5c 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -285,7 +285,7 @@ void UserIOHandler::OnDataReady() user->bytes_in += qpos; user->cmds_in++; - ServerInstance->Parser.ProcessBuffer(line, user); + ServerInstance->Parser.ProcessBuffer(user, line); if (user->quitting) return; |