summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure6
-rw-r--r--include/modules.h3
-rw-r--r--src/command_parse.cpp17
-rw-r--r--src/commands/cmd_list.cpp15
-rw-r--r--src/commands/cmd_motd.cpp6
-rw-r--r--src/commands/cmd_pass.cpp1
-rw-r--r--src/commands/cmd_ping.cpp2
-rw-r--r--src/commands/cmd_pong.cpp11
-rw-r--r--src/commands/cmd_rules.cpp6
-rw-r--r--src/commands/cmd_stats.cpp10
-rw-r--r--src/commands/cmd_user.cpp1
-rw-r--r--src/commands/cmd_who.cpp2
-rw-r--r--src/configreader.cpp3
-rw-r--r--src/modmanager_dynamic.cpp3
-rw-r--r--src/modules/m_check.cpp6
-rw-r--r--src/modules/m_hideoper.cpp6
-rw-r--r--src/modules/m_operprefix.cpp18
-rw-r--r--src/usermanager.cpp2
-rw-r--r--src/userprocess.cpp2
-rw-r--r--src/xline.cpp3
-rw-r--r--win/inspircd.rc.cmake2
21 files changed, 93 insertions, 32 deletions
diff --git a/configure b/configure
index 6a8e28fe9..425bb21af 100755
--- a/configure
+++ b/configure
@@ -33,12 +33,6 @@ BEGIN {
use strict;
use warnings FATAL => qw(all);
-use Data::Dumper;
-BEGIN {
- $Data::Dumper::Sortkeys = 1;
- $Data::Dumper::Useqq = 1;
-};
-
use File::Copy ();
use Socket;
use Cwd;
diff --git a/include/modules.h b/include/modules.h
index cd0d5aad0..9857012fc 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -1717,7 +1717,8 @@ struct AllModuleList {
break; \
} \
return TRUE; \
- }
+ } \
+ extern "C" DllExport const char inspircd_src_version[] = VERSION " r" REVISION;
#else
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_list.cpp b/src/commands/cmd_list.cpp
index 2f417bc04..2c420d1dd 100644
--- a/src/commands/cmd_list.cpp
+++ b/src/commands/cmd_list.cpp
@@ -82,14 +82,15 @@ CmdResult CommandList::Handle (const std::vector<std::string>& parameters, User
// if the channel is not private/secret, OR the user is on the channel anyway
bool n = (i->second->HasUser(user) || user->HasPrivPermission("channels/auspex"));
- if (!n && i->second->IsModeSet('p'))
+ // If we're not in the channel and +s is set on it, we want to ignore it
+ if (n || !i->second->IsModeSet('s'))
{
- /* Channel is +p and user is outside/not privileged */
- user->WriteNumeric(322, "%s * %ld :",user->nick.c_str(), users);
- }
- else
- {
- if (n || !i->second->IsModeSet('s'))
+ if (!n && i->second->IsModeSet('p'))
+ {
+ /* Channel is +p and user is outside/not privileged */
+ user->WriteNumeric(322, "%s * %ld :",user->nick.c_str(), users);
+ }
+ else
{
/* User is in the channel/privileged, channel is not +s */
user->WriteNumeric(322, "%s %s %ld :[+%s] %s",user->nick.c_str(),i->second->name.c_str(),users,i->second->ChanModes(n),i->second->topic.c_str());
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 9399b7bea..d547635ed 100644
--- a/src/commands/cmd_stats.cpp
+++ b/src/commands/cmd_stats.cpp
@@ -368,7 +368,7 @@ void CommandStats::DoStats(char statschar, User* user, string_list &results)
for (LocalUserList::iterator n = ServerInstance->Users->local_users.begin(); n != ServerInstance->Users->local_users.end(); n++)
{
LocalUser* i = *n;
- results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->dhost+"] "+ConvToStr(i->eh.getSendQSize())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(ServerInstance->Time() - i->age));
+ results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->dhost+"] "+ConvToStr(i->eh.getSendQSize())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(ServerInstance->Time() - i->signon));
}
break;
@@ -378,7 +378,7 @@ void CommandStats::DoStats(char statschar, User* user, string_list &results)
for (LocalUserList::iterator n = ServerInstance->Users->local_users.begin(); n != ServerInstance->Users->local_users.end(); n++)
{
LocalUser* i = *n;
- results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->GetIPString()+"] "+ConvToStr(i->eh.getSendQSize())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(ServerInstance->Time() - i->age));
+ results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->GetIPString()+"] "+ConvToStr(i->eh.getSendQSize())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(ServerInstance->Time() - i->signon));
}
break;
@@ -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;
}
diff --git a/src/commands/cmd_who.cpp b/src/commands/cmd_who.cpp
index 2b3242211..90c26a974 100644
--- a/src/commands/cmd_who.cpp
+++ b/src/commands/cmd_who.cpp
@@ -141,7 +141,7 @@ bool CommandWho::whomatch(User* cuser, User* user, const char* matchtext)
long seconds = ServerInstance->Duration(matchtext);
// Okay, so time matching, we want all users connected `seconds' ago
- if (user->age >= ServerInstance->Time() - seconds)
+ if (user->signon >= ServerInstance->Time() - seconds)
match = true;
}
diff --git a/src/configreader.cpp b/src/configreader.cpp
index b5d2fdb16..b3caf8c75 100644
--- a/src/configreader.cpp
+++ b/src/configreader.cpp
@@ -35,6 +35,7 @@
#endif
ServerConfig::ServerConfig()
+ : NoSnoticeStack(false)
{
WhoWasGroupSize = WhoWasMaxGroups = WhoWasMaxKeep = 0;
RawLog = NoUserDns = HideBans = HideSplits = UndernetMsgPrefix = false;
@@ -729,7 +730,7 @@ void ServerConfig::Apply(ServerConfig* old, const std::string &useruid)
if (valid)
ServerInstance->WritePID(this->PID);
- if (old)
+ if (old && valid)
{
// On first run, ports are bound later on
FailedPortList pl;
diff --git a/src/modmanager_dynamic.cpp b/src/modmanager_dynamic.cpp
index 045b488b5..050f41c75 100644
--- a/src/modmanager_dynamic.cpp
+++ b/src/modmanager_dynamic.cpp
@@ -36,7 +36,10 @@ bool ModuleManager::Load(const std::string& filename, bool defer)
{
/* Don't allow people to specify paths for modules, it doesn't work as expected */
if (filename.find('/') != std::string::npos)
+ {
+ LastModuleError = "You can't load modules with a path: " + filename;
return false;
+ }
char modfile[MAXBUF];
snprintf(modfile,MAXBUF,"%s/%s",ServerInstance->Config->ModPath.c_str(),filename.c_str());
diff --git a/src/modules/m_check.cpp b/src/modules/m_check.cpp
index 96b357f20..9c5c414f1 100644
--- a/src/modules/m_check.cpp
+++ b/src/modules/m_check.cpp
@@ -38,8 +38,10 @@ class CommandCheck : public Command
{
char timebuf[60];
struct tm *mytime = gmtime(&time);
- strftime(timebuf, 59, "%Y-%m-%d %H:%M:%S UTC (%s)", mytime);
- return std::string(timebuf);
+ strftime(timebuf, 59, "%Y-%m-%d %H:%M:%S UTC (", mytime);
+ std::string ret(timebuf);
+ ret.append(ConvToStr(time)).push_back(')');
+ return ret;
}
void dumpExt(User* user, const std::string& checkstr, Extensible* ext)
diff --git a/src/modules/m_hideoper.cpp b/src/modules/m_hideoper.cpp
index b83c7de1a..88b0c4cdf 100644
--- a/src/modules/m_hideoper.cpp
+++ b/src/modules/m_hideoper.cpp
@@ -82,7 +82,11 @@ class ModuleHideOper : public Module
if (user->IsModeSet('H') && !source->HasPrivPermission("users/auspex"))
{
// hide the "*" that marks the user as an oper from the /WHO line
- std::string::size_type pos = line.find("*");
+ std::string::size_type spcolon = line.find(" :");
+ if (spcolon == std::string::npos)
+ return; // Another module hid the user completely
+ std::string::size_type sp = line.rfind(' ', spcolon-1);
+ std::string::size_type pos = line.find('*', sp);
if (pos != std::string::npos)
line.erase(pos, 1);
// hide the line completely if doing a "/who * o" query
diff --git a/src/modules/m_operprefix.cpp b/src/modules/m_operprefix.cpp
index 62ddb6c67..9f1f6cc5e 100644
--- a/src/modules/m_operprefix.cpp
+++ b/src/modules/m_operprefix.cpp
@@ -85,7 +85,7 @@ class ModuleOperPrefixMode : public Module
{
ServerInstance->Modules->AddService(opm);
- Implementation eventlist[] = { I_OnUserPreJoin, I_OnPostOper, I_OnLoadModule, I_OnUnloadModule };
+ Implementation eventlist[] = { I_OnUserPreJoin, I_OnPostOper, I_OnLoadModule, I_OnUnloadModule, I_OnPostJoin };
ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
/* To give clients a chance to learn about the new prefix we don't give +y to opers
@@ -110,6 +110,22 @@ class ModuleOperPrefixMode : public Module
return MOD_RES_PASSTHRU;
}
+ void OnPostJoin(Membership* memb)
+ {
+ if ((!IS_LOCAL(memb->user)) || (!IS_OPER(memb->user)) || (((mw_added) && (memb->user->IsModeSet('H')))))
+ return;
+
+ if (memb->hasMode(opm.GetModeChar()))
+ return;
+
+ // The user was force joined and OnUserPreJoin() did not run. Set the operprefix now.
+ std::vector<std::string> modechange;
+ modechange.push_back(memb->chan->name);
+ modechange.push_back("+y");
+ modechange.push_back(memb->user->nick);
+ ServerInstance->SendGlobalMode(modechange, ServerInstance->FakeClient);
+ }
+
void SetOperPrefix(User* user, bool add)
{
std::vector<std::string> modechange;
diff --git a/src/usermanager.cpp b/src/usermanager.cpp
index 076277a33..1918b5c4c 100644
--- a/src/usermanager.cpp
+++ b/src/usermanager.cpp
@@ -72,7 +72,7 @@ void UserManager::AddUser(int socket, ListenSocket* via, irc::sockets::sockaddrs
(*(this->clientlist))[New->nick] = New;
New->registered = REG_NONE;
- New->signon = ServerInstance->Time() + ServerInstance->Config->dns_timeout;
+ New->signon = ServerInstance->Time();
New->lastping = 1;
ServerInstance->Users->AddLocalClone(New);
diff --git a/src/userprocess.cpp b/src/userprocess.cpp
index 9cc2e7df7..0ef95e413 100644
--- a/src/userprocess.cpp
+++ b/src/userprocess.cpp
@@ -107,7 +107,7 @@ void InspIRCd::DoBackgroundUserStuff()
break;
}
- if (curr->registered != REG_ALL && (Time() > (curr->age + curr->MyClass->GetRegTimeout())))
+ if (curr->registered != REG_ALL && (Time() > (curr->signon + curr->MyClass->GetRegTimeout())))
{
/*
* registration timeout -- didnt send USER/NICK/HOST
diff --git a/src/xline.cpp b/src/xline.cpp
index 66d24f439..b710c5c43 100644
--- a/src/xline.cpp
+++ b/src/xline.cpp
@@ -598,9 +598,6 @@ void GLine::Apply(User* u)
bool ELine::Matches(User *u)
{
- if (u->exempt)
- return false;
-
if (InspIRCd::Match(u->ident, this->identmask, ascii_case_insensitive_map))
{
if (InspIRCd::MatchCIDR(u->host, this->hostmask, ascii_case_insensitive_map) ||
diff --git a/win/inspircd.rc.cmake b/win/inspircd.rc.cmake
index 20c7839fe..ba52ad5d2 100644
--- a/win/inspircd.rc.cmake
+++ b/win/inspircd.rc.cmake
@@ -22,7 +22,7 @@ BEGIN
VALUE "FileDescription", "InspIRCd"
VALUE "FileVersion", "@FULL_VERSION@"
VALUE "InternalName", "InspIRCd"
- VALUE "LegalCopyright", "Copyright (c) 2014 InspIRCd Development Team"
+ VALUE "LegalCopyright", "Copyright (c) 2015 InspIRCd Development Team"
VALUE "OriginalFilename", "inspircd.exe"
VALUE "ProductName", "InspIRCd - The Inspire IRC Daemon"
VALUE "ProductVersion", "@FULL_VERSION@"