diff options
Diffstat (limited to 'src')
76 files changed, 320 insertions, 197 deletions
diff --git a/src/configparser.cpp b/src/configparser.cpp index 8bf9aaec2..7c03fe58a 100644 --- a/src/configparser.cpp +++ b/src/configparser.cpp @@ -91,7 +91,7 @@ struct Parser unget(ch); } - bool kv(std::vector<KeyVal>* items, std::set<std::string>& seen) + bool kv(ConfigItems* items) { std::string key; nextword(key); @@ -177,10 +177,10 @@ struct Parser value.push_back(ch); } - if (!seen.insert(key).second) + if (items->find(key) != items->end()) throw CoreException("Duplicate key '" + key + "' found"); - items->push_back(KeyVal(key, value)); + (*items)[key] = value; return true; } @@ -199,11 +199,10 @@ struct Parser if (name.empty()) throw CoreException("Empty tag name"); - std::vector<KeyVal>* items; - std::set<std::string> seen; + ConfigItems* items; tag = ConfigTag::create(name, current.filename, current.line, items); - while (kv(items, seen)) + while (kv(items)) { // Do nothing here (silences a GCC warning). } @@ -220,14 +219,14 @@ struct Parser } else if (name == "files") { - for(std::vector<KeyVal>::iterator i = items->begin(); i != items->end(); i++) + for(ConfigItems::iterator i = items->begin(); i != items->end(); i++) { stack.DoReadFile(i->first, i->second, flags, false); } } else if (name == "execfiles") { - for(std::vector<KeyVal>::iterator i = items->begin(); i != items->end(); i++) + for(ConfigItems::iterator i = items->begin(); i != items->end(); i++) { stack.DoReadFile(i->first, i->second, flags, true); } @@ -385,7 +384,7 @@ bool ParseStack::ParseFile(const std::string& path, int flags, const std::string bool ConfigTag::readString(const std::string& key, std::string& value, bool allow_lf) { - for(std::vector<KeyVal>::iterator j = items.begin(); j != items.end(); ++j) + for(ConfigItems::iterator j = items.begin(); j != items.end(); ++j) { if(j->first != key) continue; @@ -488,7 +487,7 @@ std::string ConfigTag::getTagLocation() return src_name + ":" + ConvToStr(src_line); } -ConfigTag* ConfigTag::create(const std::string& Tag, const std::string& file, int line, std::vector<KeyVal>*& Items) +ConfigTag* ConfigTag::create(const std::string& Tag, const std::string& file, int line, ConfigItems*& Items) { ConfigTag* rv = new ConfigTag(Tag, file, line); Items = &rv->items; diff --git a/src/configreader.cpp b/src/configreader.cpp index 9d327532b..8263b8737 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -46,7 +46,7 @@ ServerLimits::ServerLimits(ConfigTag* tag) static ConfigTag* CreateEmptyTag() { - std::vector<KeyVal>* items; + ConfigItems* items; return ConfigTag::create("empty", "<auto>", 0, items); } @@ -220,9 +220,9 @@ void ServerConfig::CrossCheckConnectBlocks(ServerConfig* current) if (blk_count == 0) { // No connect blocks found; make a trivial default block - std::vector<KeyVal>* items; + ConfigItems* items; ConfigTag* tag = ConfigTag::create("connect", "<auto>", 0, items); - items->push_back(std::make_pair("allow", "*")); + (*items)["allow"] = "*"; config_data.insert(std::make_pair("connect", tag)); blk_count = 1; } diff --git a/src/coremods/core_dns.cpp b/src/coremods/core_dns.cpp index 753b41f43..1040bb036 100644 --- a/src/coremods/core_dns.cpp +++ b/src/coremods/core_dns.cpp @@ -154,7 +154,7 @@ class Packet : public Query record.ttl = (input[pos] << 24) | (input[pos + 1] << 16) | (input[pos + 2] << 8) | input[pos + 3]; pos += 4; - //record.rdlength = input[pos] << 8 | input[pos + 1]; + uint16_t rdlength = input[pos] << 8 | input[pos + 1]; pos += 2; switch (record.type) @@ -200,6 +200,19 @@ class Packet : public Query break; } + case QUERY_TXT: + { + if (pos + rdlength > input_size) + throw Exception("Unable to unpack txt resource record"); + + record.rdata = std::string(reinterpret_cast<const char *>(input + pos), rdlength); + pos += rdlength; + + if (record.rdata.find_first_of("\r\n\0", 0, 3) != std::string::npos) + throw Exception("Invalid character in txt record"); + + break; + } default: break; } @@ -429,7 +442,7 @@ class MyManager : public Manager, public Timer, public EventHandler } } - void Process(DNS::Request* req) + void Process(DNS::Request* req) CXX11_OVERRIDE { if ((unloading) || (req->creator->dying)) throw Exception("Module is being unloaded"); @@ -496,13 +509,13 @@ class MyManager : public Manager, public Timer, public EventHandler ServerInstance->Timers.AddTimer(req); } - void RemoveRequest(DNS::Request* req) + void RemoveRequest(DNS::Request* req) CXX11_OVERRIDE { if (requests[req->id] == req) requests[req->id] = NULL; } - std::string GetErrorStr(Error e) + std::string GetErrorStr(Error e) CXX11_OVERRIDE { switch (e) { @@ -651,7 +664,7 @@ class MyManager : public Manager, public Timer, public EventHandler delete request; } - bool Tick(time_t now) + bool Tick(time_t now) CXX11_OVERRIDE { ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "cache: purging DNS cache"); @@ -813,7 +826,7 @@ class ModuleDNS : public Module this->manager.Rehash(DNSServer, SourceIP, SourcePort); } - void OnUnloadModule(Module* mod) + void OnUnloadModule(Module* mod) CXX11_OVERRIDE { for (unsigned int i = 0; i <= MAX_REQUEST_ID; ++i) { @@ -832,7 +845,7 @@ class ModuleDNS : public Module } } - Version GetVersion() + Version GetVersion() CXX11_OVERRIDE { return Version("DNS support", VF_CORE|VF_VENDOR); } diff --git a/src/coremods/core_hostname_lookup.cpp b/src/coremods/core_hostname_lookup.cpp index b9adc9c2e..d150b8551 100644 --- a/src/coremods/core_hostname_lookup.cpp +++ b/src/coremods/core_hostname_lookup.cpp @@ -195,7 +195,7 @@ class ModuleHostnameLookup : public Module ph = &ptrHosts; } - void OnUserInit(LocalUser *user) + void OnUserInit(LocalUser *user) CXX11_OVERRIDE { if (!DNS || !user->MyClass->resolvehostnames) { @@ -222,12 +222,12 @@ class ModuleHostnameLookup : public Module } } - ModResult OnCheckReady(LocalUser* user) + ModResult OnCheckReady(LocalUser* user) CXX11_OVERRIDE { return this->dnsLookup.get(user) ? MOD_RES_DENY : MOD_RES_PASSTHRU; } - Version GetVersion() + Version GetVersion() CXX11_OVERRIDE { return Version("Provides support for DNS lookups on connecting clients", VF_CORE|VF_VENDOR); } diff --git a/src/coremods/core_loadmodule.cpp b/src/coremods/core_loadmodule.cpp index 09c044198..fde149587 100644 --- a/src/coremods/core_loadmodule.cpp +++ b/src/coremods/core_loadmodule.cpp @@ -116,7 +116,7 @@ class CoreModLoadModule : public Module { } - Version GetVersion() + Version GetVersion() CXX11_OVERRIDE { return Version("Provides the LOADMODULE and UNLOADMODULE commands", VF_VENDOR|VF_CORE); } diff --git a/src/coremods/core_lusers.cpp b/src/coremods/core_lusers.cpp index a0d0d0205..7f1903dd0 100644 --- a/src/coremods/core_lusers.cpp +++ b/src/coremods/core_lusers.cpp @@ -151,20 +151,20 @@ class ModuleLusers : public Module { } - void OnPostConnect(User* user) + void OnPostConnect(User* user) CXX11_OVERRIDE { counters.UpdateMaxUsers(); if (user->IsModeSet(invisiblemode)) counters.invisible++; } - void OnUserQuit(User* user, const std::string& message, const std::string& oper_message) + void OnUserQuit(User* user, const std::string& message, const std::string& oper_message) CXX11_OVERRIDE { if (user->IsModeSet(invisiblemode)) counters.invisible--; } - Version GetVersion() + Version GetVersion() CXX11_OVERRIDE { return Version("LUSERS", VF_VENDOR | VF_CORE); } diff --git a/src/coremods/core_privmsg.cpp b/src/coremods/core_privmsg.cpp index cccba0850..449097a75 100644 --- a/src/coremods/core_privmsg.cpp +++ b/src/coremods/core_privmsg.cpp @@ -280,7 +280,7 @@ class ModuleCoreMessage : public Module { } - Version GetVersion() + Version GetVersion() CXX11_OVERRIDE { return Version("PRIVMSG, NOTICE", VF_CORE|VF_VENDOR); } diff --git a/src/coremods/core_stub.cpp b/src/coremods/core_stub.cpp index 91fc16241..71b0ddaea 100644 --- a/src/coremods/core_stub.cpp +++ b/src/coremods/core_stub.cpp @@ -147,7 +147,7 @@ class CoreModStub : public Module { } - Version GetVersion() + Version GetVersion() CXX11_OVERRIDE { return Version("Provides the stub commands CONNECT, LINKS, SERVER and SQUIT", VF_VENDOR|VF_CORE); } diff --git a/src/coremods/core_user/cmd_mode.cpp b/src/coremods/core_user/cmd_mode.cpp index b1790bb89..2b2652606 100644 --- a/src/coremods/core_user/cmd_mode.cpp +++ b/src/coremods/core_user/cmd_mode.cpp @@ -130,6 +130,17 @@ void CommandMode::DisplayListModes(User* user, Channel* chan, const std::string& } } +static std::string GetSnomasks(const User* user) +{ + ModeHandler* const snomask = ServerInstance->Modes.FindMode('s', MODETYPE_USER); + std::string snomaskstr = snomask->GetUserParameter(user); + // snomaskstr is empty if the snomask mode isn't set, otherwise it begins with a '+'. + // In the former case output a "+", not an empty string. + if (snomaskstr.empty()) + snomaskstr.push_back('+'); + return snomaskstr; +} + void CommandMode::DisplayCurrentModes(User* user, User* targetuser, Channel* targetchannel) { if (targetchannel) @@ -140,20 +151,20 @@ void CommandMode::DisplayCurrentModes(User* user, User* targetuser, Channel* tar } else { - if (targetuser == user || user->HasPrivPermission("users/auspex")) + if (targetuser == user) { // Display user's current mode string - // XXX: Use WriteServ() because WriteNumeric() assumes the target (i.e. next word after the number) - // is 'user' and puts his nick there which is not what we want - user->WriteServ("%03d %s :+%s", RPL_UMODEIS, targetuser->nick.c_str(), targetuser->FormatModes()); + user->WriteNumeric(RPL_UMODEIS, targetuser->GetModeLetters()); if (targetuser->IsOper()) - { - ModeHandler* snomask = ServerInstance->Modes->FindMode('s', MODETYPE_USER); - std::string snomaskstr = snomask->GetUserParameter(user); - // snomaskstr is empty if the snomask mode isn't set, otherwise it begins with a '+'. - // In the former case output a "+", not an empty string. - user->WriteServ("%03d %s %s%s :Server notice mask", RPL_SNOMASKIS, targetuser->nick.c_str(), (snomaskstr.empty() ? "+" : ""), snomaskstr.c_str()); - } + user->WriteNumeric(RPL_SNOMASKIS, GetSnomasks(targetuser), "Server notice mask"); + } + else if (user->HasPrivPermission("users/auspex")) + { + // Querying the modes of another user. + // We cannot use RPL_UMODEIS because that's only for showing the user's own modes. + user->WriteNumeric(RPL_OTHERUMODEIS, targetuser->nick, targetuser->GetModeLetters()); + if (targetuser->IsOper()) + user->WriteNumeric(RPL_OTHERSNOMASKIS, targetuser->nick, GetSnomasks(targetuser), "Server notice mask"); } else { diff --git a/src/coremods/core_who.cpp b/src/coremods/core_who.cpp index 739c675a9..677a1eb6d 100644 --- a/src/coremods/core_who.cpp +++ b/src/coremods/core_who.cpp @@ -38,14 +38,18 @@ class CommandWho : public Command bool opt_time; ChanModeReference secretmode; ChanModeReference privatemode; + UserModeReference hidechansmode; UserModeReference invisiblemode; - Membership* get_first_visible_channel(User* u) + Membership* get_first_visible_channel(User* source, User* u) { for (User::ChanList::iterator i = u->chans.begin(); i != u->chans.end(); ++i) { Membership* memb = *i; - if (!memb->chan->IsModeSet(secretmode)) + + /* XXX move the +I check into m_hidechans */ + bool has_modes = memb->chan->IsModeSet(secretmode) || memb->chan->IsModeSet(privatemode) || u->IsModeSet(hidechansmode); + if (source == u || !has_modes || memb->chan->HasUser(source)) return memb; } return NULL; @@ -58,6 +62,7 @@ class CommandWho : public Command : Command(parent, "WHO", 1) , secretmode(parent, "secret") , privatemode(parent, "private") + , hidechansmode(parent, "hidechans") , invisiblemode(parent, "invisible") { syntax = "<server>|<nickname>|<channel>|<realname>|<host>|0 [ohurmMiaplf]"; @@ -189,7 +194,7 @@ bool CommandWho::CanView(Channel* chan, User* user) void CommandWho::SendWhoLine(User* user, const std::vector<std::string>& parms, Membership* memb, User* u, std::vector<Numeric::Numeric>& whoresults) { if (!memb) - memb = get_first_visible_channel(u); + memb = get_first_visible_channel(user, u); Numeric::Numeric wholine(RPL_WHOREPLY); wholine.push(memb ? memb->chan->name : "*").push(u->ident); diff --git a/src/coremods/core_whois.cpp b/src/coremods/core_whois.cpp index ed5c1cda0..81e62c8e5 100644 --- a/src/coremods/core_whois.cpp +++ b/src/coremods/core_whois.cpp @@ -211,11 +211,11 @@ void CommandWhois::DoWhois(LocalUser* user, User* dest, unsigned long signon, un { if (dest->IsModeSet(snomaskmode)) { - whois.SendLine(379, InspIRCd::Format("is using modes +%s %s", dest->FormatModes(), snomaskmode->GetUserParameter(dest).c_str())); + whois.SendLine(379, InspIRCd::Format("is using modes %s %s", dest->GetModeLetters().c_str(), snomaskmode->GetUserParameter(dest).c_str())); } else { - whois.SendLine(379, InspIRCd::Format("is using modes +%s", dest->FormatModes())); + whois.SendLine(379, InspIRCd::Format("is using modes %s", dest->GetModeLetters().c_str())); } } diff --git a/src/coremods/core_whowas.cpp b/src/coremods/core_whowas.cpp index f52fb0174..0bb47b273 100644 --- a/src/coremods/core_whowas.cpp +++ b/src/coremods/core_whowas.cpp @@ -259,13 +259,13 @@ class ModuleWhoWas : public Module { } - void OnGarbageCollect() + void OnGarbageCollect() CXX11_OVERRIDE { // Remove all entries older than MaxKeep cmd.manager.Maintain(); } - void OnUserQuit(User* user, const std::string& message, const std::string& oper_message) + void OnUserQuit(User* user, const std::string& message, const std::string& oper_message) CXX11_OVERRIDE { cmd.manager.Add(user); } @@ -288,7 +288,7 @@ class ModuleWhoWas : public Module cmd.manager.UpdateConfig(NewGroupSize, NewMaxGroups, NewMaxKeep); } - Version GetVersion() + Version GetVersion() CXX11_OVERRIDE { return Version("WHOWAS", VF_VENDOR); } diff --git a/src/coremods/core_xline/cmd_gline.cpp b/src/coremods/core_xline/cmd_gline.cpp index 3f042c366..49932ba9d 100644 --- a/src/coremods/core_xline/cmd_gline.cpp +++ b/src/coremods/core_xline/cmd_gline.cpp @@ -26,7 +26,6 @@ CommandGline::CommandGline(Module* parent) : Command(parent, "GLINE", 1, 3) { flags_needed = 'o'; - Penalty = 0; syntax = "<ident@host> [<duration> :<reason>]"; } diff --git a/src/coremods/core_xline/cmd_kline.cpp b/src/coremods/core_xline/cmd_kline.cpp index ee85fdd1d..db8862d37 100644 --- a/src/coremods/core_xline/cmd_kline.cpp +++ b/src/coremods/core_xline/cmd_kline.cpp @@ -26,7 +26,6 @@ CommandKline::CommandKline(Module* parent) : Command(parent, "KLINE", 1, 3) { flags_needed = 'o'; - Penalty = 0; syntax = "<ident@host> [<duration> :<reason>]"; } diff --git a/src/coremods/core_xline/cmd_qline.cpp b/src/coremods/core_xline/cmd_qline.cpp index 955efeaf0..6dc0da9ba 100644 --- a/src/coremods/core_xline/cmd_qline.cpp +++ b/src/coremods/core_xline/cmd_qline.cpp @@ -27,7 +27,6 @@ CommandQline::CommandQline(Module* parent) : Command(parent, "QLINE", 1, 3) { flags_needed = 'o'; - Penalty = 0; syntax = "<nick> [<duration> :<reason>]"; } diff --git a/src/coremods/core_xline/cmd_zline.cpp b/src/coremods/core_xline/cmd_zline.cpp index 859be1004..1bc7e8afd 100644 --- a/src/coremods/core_xline/cmd_zline.cpp +++ b/src/coremods/core_xline/cmd_zline.cpp @@ -27,7 +27,6 @@ CommandZline::CommandZline(Module* parent) : Command(parent, "ZLINE", 1, 3) { flags_needed = 'o'; - Penalty = 0; syntax = "<ipmask> [<duration> :<reason>]"; } diff --git a/src/coremods/core_xline/core_xline.h b/src/coremods/core_xline/core_xline.h index d4ad498a0..5b34e7a4d 100644 --- a/src/coremods/core_xline/core_xline.h +++ b/src/coremods/core_xline/core_xline.h @@ -133,7 +133,6 @@ class CommandQline : public Command /** Handle command. * @param parameters The parameters to the command - * @param pcnt The number of parameters passed to the command * @param user The user issuing the command * @return A value from CmdResult to indicate command success or failure. */ diff --git a/src/inspircd.cpp b/src/inspircd.cpp index 5fe2ef076..0c9b67910 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -343,7 +343,7 @@ InspIRCd::InspIRCd(int argc, char** argv) : if (do_debug) { - FileWriter* fw = new FileWriter(stdout); + FileWriter* fw = new FileWriter(stdout, 1); FileLogStream* fls = new FileLogStream(LOG_RAWIO, fw); Logs->AddLogTypes("*", fls, true); } diff --git a/src/logger.cpp b/src/logger.cpp index 5b4a948ee..e3e956325 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -120,7 +120,7 @@ void LogManager::OpenFileLogs() struct tm *mytime = gmtime(&time); strftime(realtarget, sizeof(realtarget), target.c_str(), mytime); FILE* f = fopen(realtarget, "a"); - fw = new FileWriter(f); + fw = new FileWriter(f, static_cast<unsigned int>(tag->getInt("flush", 20, 1, INT_MAX))); logmap.insert(std::make_pair(target, fw)); } else @@ -309,8 +309,10 @@ void LogManager::Log(const std::string &type, LogLevel loglevel, const std::stri } -FileWriter::FileWriter(FILE* logfile) -: log(logfile), writeops(0) +FileWriter::FileWriter(FILE* logfile, unsigned int flushcount) + : log(logfile) + , flush(flushcount) + , writeops(0) { } @@ -322,7 +324,7 @@ void FileWriter::WriteLogLine(const std::string &line) // throw CoreException("FileWriter::WriteLogLine called with a closed logfile"); fputs(line.c_str(), log); - if (++writeops % 20 == 0) + if (++writeops % flush == 0) { fflush(log); } diff --git a/src/mode.cpp b/src/mode.cpp index fec614ab4..22173c189 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -58,7 +58,7 @@ bool ModeHandler::NeedsParam(bool adding) const return false; } -std::string ModeHandler::GetUserParameter(User* user) +std::string ModeHandler::GetUserParameter(const User* user) const { return ""; } diff --git a/src/modes/umode_s.cpp b/src/modes/umode_s.cpp index f0fa5e94b..ffad21662 100644 --- a/src/modes/umode_s.cpp +++ b/src/modes/umode_s.cpp @@ -50,7 +50,7 @@ ModeAction ModeUserServerNoticeMask::OnModeChange(User* source, User* dest, Chan return MODEACTION_DENY; } -std::string ModeUserServerNoticeMask::GetUserParameter(User* user) +std::string ModeUserServerNoticeMask::GetUserParameter(const User* user) const { std::string ret; if (!user->IsModeSet(this)) diff --git a/src/modmanager_static.cpp b/src/modmanager_static.cpp index 5c04a7680..9a385dd3c 100644 --- a/src/modmanager_static.cpp +++ b/src/modmanager_static.cpp @@ -72,7 +72,7 @@ class AllModule : public Module stdalgo::delete_all(cmds); } - Version GetVersion() + Version GetVersion() CXX11_OVERRIDE { return Version("All commands", VF_VENDOR|VF_CORE); } diff --git a/src/modules/extra/m_pgsql.cpp b/src/modules/extra/m_pgsql.cpp index 5f6f6e30f..6835cb558 100644 --- a/src/modules/extra/m_pgsql.cpp +++ b/src/modules/extra/m_pgsql.cpp @@ -159,7 +159,7 @@ class SQLConn : public SQLProvider, public EventHandler } } - CullResult cull() + CullResult cull() CXX11_OVERRIDE { this->SQLProvider::cull(); ServerInstance->Modules->DelService(*this); @@ -389,7 +389,7 @@ restart: } } - void submit(SQLQuery *req, const std::string& q) + void submit(SQLQuery *req, const std::string& q) CXX11_OVERRIDE { if (qinprog.q.empty()) { @@ -402,7 +402,7 @@ restart: } } - void submit(SQLQuery *req, const std::string& q, const ParamL& p) + void submit(SQLQuery *req, const std::string& q, const ParamL& p) CXX11_OVERRIDE { std::string res; unsigned int param = 0; @@ -427,7 +427,7 @@ restart: submit(req, res); } - void submit(SQLQuery *req, const std::string& q, const ParamM& p) + void submit(SQLQuery *req, const std::string& q, const ParamM& p) CXX11_OVERRIDE { std::string res; for(std::string::size_type i = 0; i < q.length(); i++) diff --git a/src/modules/m_abbreviation.cpp b/src/modules/m_abbreviation.cpp index 85709080f..2a38bd3a6 100644 --- a/src/modules/m_abbreviation.cpp +++ b/src/modules/m_abbreviation.cpp @@ -22,7 +22,7 @@ class ModuleAbbreviation : public Module { public: - void Prioritize() + void Prioritize() CXX11_OVERRIDE { ServerInstance->Modules->SetPriority(this, I_OnPreCommand, PRIORITY_FIRST); } diff --git a/src/modules/m_alias.cpp b/src/modules/m_alias.cpp index c6e53f0cf..e99d9dab5 100644 --- a/src/modules/m_alias.cpp +++ b/src/modules/m_alias.cpp @@ -352,7 +352,7 @@ class ModuleAlias : public Module ServerInstance->Parser.CallHandler(command, pars, user); } - void Prioritize() + void Prioritize() CXX11_OVERRIDE { // Prioritise after spanningtree so that channel aliases show the alias before the effects. Module* linkmod = ServerInstance->Modules->Find("m_spanningtree.so"); diff --git a/src/modules/m_bcrypt.cpp b/src/modules/m_bcrypt.cpp index 8a025a0d6..1698b0727 100644 --- a/src/modules/m_bcrypt.cpp +++ b/src/modules/m_bcrypt.cpp @@ -978,7 +978,7 @@ class ModuleBCrypt : public Module bcrypt.rounds = conf->getInt("rounds", 10, 1); } - Version GetVersion() + Version GetVersion() CXX11_OVERRIDE { return Version("Implements bcrypt hashing", VF_VENDOR); } diff --git a/src/modules/m_cgiirc.cpp b/src/modules/m_cgiirc.cpp index 09d6e5fdf..5eba5ce35 100644 --- a/src/modules/m_cgiirc.cpp +++ b/src/modules/m_cgiirc.cpp @@ -77,6 +77,7 @@ class CommandWebirc : public Command realhost("cgiirc_realhost", ExtensionItem::EXT_USER, Creator) , realip("cgiirc_realip", ExtensionItem::EXT_USER, Creator) { + allow_empty_last_param = false; works_before_reg = true; this->syntax = "password client hostname ip"; } @@ -85,6 +86,14 @@ class CommandWebirc : public Command if(user->registered == REG_ALL) return CMD_FAILURE; + irc::sockets::sockaddrs ipaddr; + if (!irc::sockets::aptosa(parameters[3], 0, ipaddr)) + { + IS_LOCAL(user)->CommandFloodPenalty += 5000; + ServerInstance->SNO->WriteGlobalSno('a', "Connecting user %s tried to use WEBIRC but gave an invalid IP address.", user->GetFullRealHost().c_str()); + return CMD_FAILURE; + } + for(CGIHostlist::iterator iter = Hosts.begin(); iter != Hosts.end(); iter++) { if(InspIRCd::Match(user->host, iter->hostmask, ascii_case_insensitive_map) || InspIRCd::MatchCIDR(user->GetIPString(), iter->hostmask, ascii_case_insensitive_map)) @@ -112,6 +121,7 @@ class CommandWebirc : public Command } } + IS_LOCAL(user)->CommandFloodPenalty += 5000; ServerInstance->SNO->WriteGlobalSno('w', "Connecting user %s tried to use WEBIRC, but didn't match any configured webirc blocks.", user->GetFullRealHost().c_str()); return CMD_FAILURE; } diff --git a/src/modules/m_check.cpp b/src/modules/m_check.cpp index f4123466e..2cb45ad43 100644 --- a/src/modules/m_check.cpp +++ b/src/modules/m_check.cpp @@ -169,7 +169,7 @@ class CommandCheck : public Command context.Write("nuh", targuser->GetFullHost()); context.Write("realnuh", targuser->GetFullRealHost()); context.Write("realname", targuser->fullname); - context.Write("modes", std::string("+") + targuser->FormatModes()); + context.Write("modes", targuser->GetModeLetters()); context.Write("snomasks", GetSnomasks(targuser)); context.Write("server", targuser->server->GetName()); context.Write("uid", targuser->uuid); diff --git a/src/modules/m_clearchan.cpp b/src/modules/m_clearchan.cpp index 4142f81d1..1b4b8724a 100644 --- a/src/modules/m_clearchan.cpp +++ b/src/modules/m_clearchan.cpp @@ -150,7 +150,7 @@ class ModuleClearChan : public Module { } - void init() + void init() CXX11_OVERRIDE { // Only attached while we are working; don't react to events otherwise ServerInstance->Modules->DetachAll(this); diff --git a/src/modules/m_cloaking.cpp b/src/modules/m_cloaking.cpp index 890c799f2..cb3fdac1a 100644 --- a/src/modules/m_cloaking.cpp +++ b/src/modules/m_cloaking.cpp @@ -89,6 +89,10 @@ class CloakUser : public ModeHandler if (adding) { + // assume this is more correct + if (user->registered != REG_ALL && user->host != user->dhost) + return MODEACTION_DENY; + std::string* cloak = ext.get(user); if (!cloak) @@ -139,7 +143,6 @@ class ModuleCloaking : public Module std::string prefix; std::string suffix; std::string key; - const char* xtab[4]; dynamic_reference<HashProvider> Hash; ModuleCloaking() : cu(this), mode(MODE_OPAQUE), ck(this), Hash(this, "hash/md5") @@ -286,7 +289,7 @@ class ModuleCloaking : public Module return MOD_RES_PASSTHRU; } - void Prioritize() + void Prioritize() CXX11_OVERRIDE { /* Needs to be after m_banexception etc. */ ServerInstance->Modules->SetPriority(this, I_OnCheckBan, PRIORITY_LAST); @@ -343,11 +346,14 @@ class ModuleCloaking : public Module { std::string chost; + irc::sockets::sockaddrs hostip; + bool host_is_ip = irc::sockets::aptosa(host, ip.port(), hostip) && hostip == ip; + switch (mode) { case MODE_HALF_CLOAK: { - if (ipstr != host) + if (!host_is_ip) chost = prefix + SegmentCloak(host, 1, 6) + LastTwoDomainParts(host); if (chost.empty() || chost.length() > 50) chost = SegmentIP(ip, false); diff --git a/src/modules/m_conn_join.cpp b/src/modules/m_conn_join.cpp index b22dbdf4d..bd8d89dc9 100644 --- a/src/modules/m_conn_join.cpp +++ b/src/modules/m_conn_join.cpp @@ -78,7 +78,7 @@ class ModuleConnJoin : public Module defdelay = tag->getInt("delay", 0, 0, 60); } - void Prioritize() + void Prioritize() CXX11_OVERRIDE { ServerInstance->Modules->SetPriority(this, I_OnPostConnect, PRIORITY_LAST); } diff --git a/src/modules/m_conn_umodes.cpp b/src/modules/m_conn_umodes.cpp index 7a8d66ae7..0b708641e 100644 --- a/src/modules/m_conn_umodes.cpp +++ b/src/modules/m_conn_umodes.cpp @@ -25,7 +25,7 @@ class ModuleModesOnConnect : public Module { public: - void Prioritize() + void Prioritize() CXX11_OVERRIDE { // for things like +x on connect, important, otherwise we have to resort to config order (bleh) -- w00t ServerInstance->Modules->SetPriority(this, I_OnUserConnect, PRIORITY_FIRST); diff --git a/src/modules/m_connectban.cpp b/src/modules/m_connectban.cpp index fcb4b09ed..e0f9717c4 100644 --- a/src/modules/m_connectban.cpp +++ b/src/modules/m_connectban.cpp @@ -95,7 +95,7 @@ class ModuleConnectBan : public Module } } - void OnGarbageCollect() + void OnGarbageCollect() CXX11_OVERRIDE { ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Clearing map."); connects.clear(); diff --git a/src/modules/m_dnsbl.cpp b/src/modules/m_dnsbl.cpp index 73ecd02a6..752a0d7a5 100644 --- a/src/modules/m_dnsbl.cpp +++ b/src/modules/m_dnsbl.cpp @@ -70,6 +70,14 @@ class DNSBLResolver : public DNS::Request if (!ans_record) return; + // All replies should be in 127.0.0.0/8 + if (ans_record->rdata.compare(0, 4, "127.") != 0) + { + ServerInstance->SNO->WriteGlobalSno('a', "DNSBL: %s returned address outside of acceptable subnet 127.0.0.0/8: %s", ConfEntry->domain.c_str(), ans_record->rdata.c_str()); + ConfEntry->stats_misses++; + return; + } + int i = countExt.get(them); if (i) countExt.set(them, i - 1); @@ -175,7 +183,7 @@ class DNSBLResolver : public DNS::Request if (ServerInstance->XLines->AddLine(zl,NULL)) { std::string timestr = InspIRCd::TimeString(zl->expiry); - ServerInstance->SNO->WriteGlobalSno('x',"Z:line added due to DNSBL match on *@%s to expire on %s: %s", + ServerInstance->SNO->WriteGlobalSno('x',"Z:line added due to DNSBL match on %s to expire on %s: %s", them->GetIPString().c_str(), timestr.c_str(), reason.c_str()); ServerInstance->XLines->ApplyLines(); } diff --git a/src/modules/m_filter.cpp b/src/modules/m_filter.cpp index bd19a60ba..0badd1377 100644 --- a/src/modules/m_filter.cpp +++ b/src/modules/m_filter.cpp @@ -176,7 +176,7 @@ class ModuleFilter : public Module ExemptTargetSet exemptednicks; ModuleFilter(); - CullResult cull(); + CullResult cull() CXX11_OVERRIDE; ModResult OnUserPreMessage(User* user, void* dest, int target_type, std::string& text, char status, CUList& exempt_list, MessageType msgtype) CXX11_OVERRIDE; FilterResult* FilterMatch(User* user, const std::string &text, int flags); bool DeleteFilter(const std::string &freeform); diff --git a/src/modules/m_flashpolicyd.cpp b/src/modules/m_flashpolicyd.cpp index 8f847e111..38b7be73f 100644 --- a/src/modules/m_flashpolicyd.cpp +++ b/src/modules/m_flashpolicyd.cpp @@ -146,7 +146,7 @@ class ModuleFlashPD : public Module </cross-domain-policy>"; } - CullResult cull() + CullResult cull() CXX11_OVERRIDE { for (insp::intrusive_list<FlashPDSocket>::const_iterator i = sockets.begin(); i != sockets.end(); ++i) { diff --git a/src/modules/m_hostcycle.cpp b/src/modules/m_hostcycle.cpp index b33c101ef..621f06a27 100644 --- a/src/modules/m_hostcycle.cpp +++ b/src/modules/m_hostcycle.cpp @@ -40,6 +40,8 @@ class ModuleHostCycle : public Module FOREACH_MOD(OnBuildNeighborList, (user, include_chans, exceptions)); + // Users shouldn't see themselves quitting when host cycling + exceptions.erase(user); for (std::map<User*,bool>::iterator i = exceptions.begin(); i != exceptions.end(); ++i) { LocalUser* u = IS_LOCAL(i->first); diff --git a/src/modules/m_httpd.cpp b/src/modules/m_httpd.cpp index 6055d1f77..35ae9abe5 100644 --- a/src/modules/m_httpd.cpp +++ b/src/modules/m_httpd.cpp @@ -224,7 +224,7 @@ class HttpServerSocket : public BufferedSocket, public Timer, public insp::intru WriteData("\r\n"); } - void OnDataReady() + void OnDataReady() CXX11_OVERRIDE { if (InternalState == HTTP_SERVE_RECV_POSTDATA) { @@ -415,7 +415,7 @@ class ModuleHttpServer : public Module return MOD_RES_ALLOW; } - void OnUnloadModule(Module* mod) + void OnUnloadModule(Module* mod) CXX11_OVERRIDE { for (insp::intrusive_list<HttpServerSocket>::const_iterator i = sockets.begin(); i != sockets.end(); ) { diff --git a/src/modules/m_httpd_config.cpp b/src/modules/m_httpd_config.cpp index 6fd7f4050..11c82c031 100644 --- a/src/modules/m_httpd_config.cpp +++ b/src/modules/m_httpd_config.cpp @@ -81,8 +81,8 @@ class ModuleHttpConfig : public Module, public HTTPRequestEventListener for (ConfigDataHash::iterator x = ServerInstance->Config->config_data.begin(); x != ServerInstance->Config->config_data.end(); ++x) { data << "<" << x->first << " "; - ConfigTag* tag = x->second; - for (std::vector<KeyVal>::const_iterator j = tag->getItems().begin(); j != tag->getItems().end(); j++) + const ConfigItems& items = x->second->getItems(); + for (ConfigItems::const_iterator j = items.begin(); j != items.end(); j++) { data << Sanitize(j->first) << "="" << Sanitize(j->second) << "" "; } diff --git a/src/modules/m_httpd_stats.cpp b/src/modules/m_httpd_stats.cpp index eb8e856ac..62ae0c204 100644 --- a/src/modules/m_httpd_stats.cpp +++ b/src/modules/m_httpd_stats.cpp @@ -189,7 +189,7 @@ class ModuleHttpStats : public Module, public HTTPRequestEventListener data << "<away>" << Sanitize(u->awaymsg) << "</away><awaytime>" << u->awaytime << "</awaytime>"; if (u->IsOper()) data << "<opertype>" << Sanitize(u->oper->name) << "</opertype>"; - data << "<modes>" << u->FormatModes() << "</modes><ident>" << Sanitize(u->ident) << "</ident>"; + data << "<modes>" << u->GetModeLetters().substr(1) << "</modes><ident>" << Sanitize(u->ident) << "</ident>"; LocalUser* lu = IS_LOCAL(u); if (lu) data << "<port>" << lu->GetServerPort() << "</port><servaddr>" @@ -211,7 +211,7 @@ class ModuleHttpStats : public Module, public HTTPRequestEventListener data << "<server>"; data << "<servername>" << b->servername << "</servername>"; data << "<parentname>" << b->parentname << "</parentname>"; - data << "<gecos>" << b->gecos << "</gecos>"; + data << "<gecos>" << Sanitize(b->gecos) << "</gecos>"; data << "<usercount>" << b->usercount << "</usercount>"; // This is currently not implemented, so, commented out. // data << "<opercount>" << b->opercount << "</opercount>"; diff --git a/src/modules/m_ircv3.cpp b/src/modules/m_ircv3.cpp index 9e94e556d..543fb49a4 100644 --- a/src/modules/m_ircv3.cpp +++ b/src/modules/m_ircv3.cpp @@ -169,7 +169,7 @@ class ModuleIRCv3 : public Module, public AccountEventListener last_excepts.clear(); } - void Prioritize() + void Prioritize() CXX11_OVERRIDE { ServerInstance->Modules->SetPriority(this, I_OnUserJoin, PRIORITY_LAST); } diff --git a/src/modules/m_ldapauth.cpp b/src/modules/m_ldapauth.cpp index 7da63284a..fedf02b4d 100644 --- a/src/modules/m_ldapauth.cpp +++ b/src/modules/m_ldapauth.cpp @@ -406,9 +406,22 @@ public: return MOD_RES_DENY; } + std::string what; + std::string::size_type pos = user->password.find(':'); + if (pos != std::string::npos) + { + what = attribute + "=" + user->password.substr(0, pos); + + // Trim the user: prefix, leaving just 'pass' for later password check + user->password = user->password.substr(pos + 1); + } + else + { + what = attribute + "=" + (useusername ? user->ident : user->nick); + } + try { - std::string what = attribute + "=" + (useusername ? user->ident : user->nick); LDAP->BindAsManager(new AdminBindInterface(this, LDAP.GetProvider(), user->uuid, base, what)); } catch (LDAPException &ex) diff --git a/src/modules/m_md5.cpp b/src/modules/m_md5.cpp index 6cec05a18..26ff4cffc 100644 --- a/src/modules/m_md5.cpp +++ b/src/modules/m_md5.cpp @@ -61,23 +61,13 @@ class MD5Provider : public HashProvider } while (--words); } - void MD5Init(MD5Context *ctx, unsigned int* ikey = NULL) + void MD5Init(MD5Context *ctx) { /* These are the defaults for md5 */ - if (!ikey) - { - ctx->buf[0] = 0x67452301; - ctx->buf[1] = 0xefcdab89; - ctx->buf[2] = 0x98badcfe; - ctx->buf[3] = 0x10325476; - } - else - { - ctx->buf[0] = ikey[0]; - ctx->buf[1] = ikey[1]; - ctx->buf[2] = ikey[2]; - ctx->buf[3] = ikey[3]; - } + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; ctx->bytes[0] = 0; ctx->bytes[1] = 0; @@ -236,10 +226,10 @@ class MD5Provider : public HashProvider } - void MyMD5(void *dest, void *orig, int len, unsigned int* ikey) + void MyMD5(void *dest, void *orig, int len) { MD5Context context; - MD5Init(&context, ikey); + MD5Init(&context); MD5Update(&context, (const unsigned char*)orig, len); MD5Final((unsigned char*)dest, &context); } @@ -248,7 +238,7 @@ class MD5Provider : public HashProvider std::string GenerateRaw(const std::string& data) { char res[16]; - MyMD5(res, (void*)data.data(), data.length(), NULL); + MyMD5(res, (void*)data.data(), data.length()); return std::string(res, 16); } diff --git a/src/modules/m_messageflood.cpp b/src/modules/m_messageflood.cpp index 7323605cb..d89de49eb 100644 --- a/src/modules/m_messageflood.cpp +++ b/src/modules/m_messageflood.cpp @@ -150,7 +150,7 @@ class ModuleMsgFlood : public Module return MOD_RES_PASSTHRU; } - void Prioritize() + void Prioritize() CXX11_OVERRIDE { // we want to be after all modules that might deny the message (e.g. m_muteban, m_noctcp, m_blockcolor, etc.) ServerInstance->Modules->SetPriority(this, I_OnUserPreMessage, PRIORITY_LAST); diff --git a/src/modules/m_mlock.cpp b/src/modules/m_mlock.cpp index d3ab5b9fd..2a0410bed 100644 --- a/src/modules/m_mlock.cpp +++ b/src/modules/m_mlock.cpp @@ -34,7 +34,7 @@ class ModuleMLock : public Module return Version("Implements the ability to have server-side MLOCK enforcement.", VF_VENDOR); } - ModResult OnRawMode(User* source, Channel* channel, ModeHandler* mh, const std::string& parameter, bool adding) + ModResult OnRawMode(User* source, Channel* channel, ModeHandler* mh, const std::string& parameter, bool adding) CXX11_OVERRIDE { if (!channel) return MOD_RES_PASSTHRU; diff --git a/src/modules/m_namedmodes.cpp b/src/modules/m_namedmodes.cpp index 7a86c9e3c..7f2687d66 100644 --- a/src/modules/m_namedmodes.cpp +++ b/src/modules/m_namedmodes.cpp @@ -124,7 +124,7 @@ class ModuleNamedModes : public Module return Version("Provides the ability to manipulate modes via long names.",VF_VENDOR); } - void Prioritize() + void Prioritize() CXX11_OVERRIDE { ServerInstance->Modules->SetPriority(this, I_OnPreMode, PRIORITY_FIRST); } diff --git a/src/modules/m_nicklock.cpp b/src/modules/m_nicklock.cpp index 35845c8d8..6e22a69bb 100644 --- a/src/modules/m_nicklock.cpp +++ b/src/modules/m_nicklock.cpp @@ -157,7 +157,7 @@ class ModuleNickLock : public Module return MOD_RES_PASSTHRU; } - void Prioritize() + void Prioritize() CXX11_OVERRIDE { Module *nflood = ServerInstance->Modules->Find("m_nickflood.so"); ServerInstance->Modules->SetPriority(this, I_OnUserPreNick, PRIORITY_BEFORE, nflood); diff --git a/src/modules/m_ojoin.cpp b/src/modules/m_ojoin.cpp index 2573e8b78..76e66bdc2 100644 --- a/src/modules/m_ojoin.cpp +++ b/src/modules/m_ojoin.cpp @@ -34,7 +34,7 @@ class CommandOjoin : public SplitCommand : SplitCommand(parent, "OJOIN", 1) , npmh(&mode) { - flags_needed = 'o'; Penalty = 0; syntax = "<channel>"; + flags_needed = 'o'; syntax = "<channel>"; active = false; } @@ -150,7 +150,7 @@ class ModuleOjoin : public Module return MOD_RES_DENY; } - void Prioritize() + void Prioritize() CXX11_OVERRIDE { ServerInstance->Modules->SetPriority(this, I_OnUserPreJoin, PRIORITY_FIRST); } diff --git a/src/modules/m_operprefix.cpp b/src/modules/m_operprefix.cpp index d66f99450..b355047ee 100644 --- a/src/modules/m_operprefix.cpp +++ b/src/modules/m_operprefix.cpp @@ -72,7 +72,7 @@ class ModuleOperPrefixMode : public Module return MOD_RES_PASSTHRU; } - void OnPostJoin(Membership* memb) + void OnPostJoin(Membership* memb) CXX11_OVERRIDE { if ((!IS_LOCAL(memb->user)) || (!memb->user->IsOper()) || (memb->user->IsModeSet(hideopermode))) return; @@ -105,7 +105,7 @@ class ModuleOperPrefixMode : public Module return Version("Gives opers cmode +y which provides a staff prefix.", VF_VENDOR); } - void Prioritize() + void Prioritize() CXX11_OVERRIDE { // m_opermodes may set +H on the oper to hide him, we don't want to set the oper prefix in that case Module* opermodes = ServerInstance->Modules->Find("m_opermodes.so"); diff --git a/src/modules/m_override.cpp b/src/modules/m_override.cpp index 9cfc3aed0..fd09dd6ec 100644 --- a/src/modules/m_override.cpp +++ b/src/modules/m_override.cpp @@ -121,7 +121,8 @@ class ModuleOverride : public Module if (source->IsOper() && CanOverride(source,"KICK")) { // If the kicker's status is less than the target's, or the kicker's status is less than or equal to voice - if ((memb->chan->GetPrefixValue(source) < memb->getRank()) || (memb->chan->GetPrefixValue(source) <= VOICE_VALUE)) + if ((memb->chan->GetPrefixValue(source) < memb->getRank()) || (memb->chan->GetPrefixValue(source) <= VOICE_VALUE) || + (memb->chan->GetPrefixValue(source) == HALFOP_VALUE && memb->getRank() == HALFOP_VALUE)) { ServerInstance->SNO->WriteGlobalSno('v',source->nick+" used oper override to kick "+memb->user->nick+" on "+memb->chan->name+" ("+reason+")"); return MOD_RES_ALLOW; diff --git a/src/modules/m_permchannels.cpp b/src/modules/m_permchannels.cpp index 9e77bd60e..0f2a2ef6f 100644 --- a/src/modules/m_permchannels.cpp +++ b/src/modules/m_permchannels.cpp @@ -244,6 +244,10 @@ public: mode->OnModeChange(ServerInstance->FakeClient, ServerInstance->FakeClient, c, par, true); } } + + // We always apply the permchannels mode to permanent channels. + par.clear(); + p.OnModeChange(ServerInstance->FakeClient, ServerInstance->FakeClient, c, par, true); } } } @@ -269,7 +273,7 @@ public: dirty = false; } - void Prioritize() + void Prioritize() CXX11_OVERRIDE { // XXX: Load the DB here because the order in which modules are init()ed at boot is // alphabetical, this means we must wait until all modules have done their init() diff --git a/src/modules/m_rline.cpp b/src/modules/m_rline.cpp index 97fbf169a..e77a00b6d 100644 --- a/src/modules/m_rline.cpp +++ b/src/modules/m_rline.cpp @@ -333,7 +333,7 @@ class ModuleRLine : public Module } } - void Prioritize() + void Prioritize() CXX11_OVERRIDE { Module* mod = ServerInstance->Modules->Find("m_cgiirc.so"); ServerInstance->Modules->SetPriority(this, I_OnUserRegister, PRIORITY_AFTER, mod); diff --git a/src/modules/m_sajoin.cpp b/src/modules/m_sajoin.cpp index 9d87360ec..8bf865319 100644 --- a/src/modules/m_sajoin.cpp +++ b/src/modules/m_sajoin.cpp @@ -29,7 +29,7 @@ class CommandSajoin : public Command CommandSajoin(Module* Creator) : Command(Creator,"SAJOIN", 1) { allow_empty_last_param = false; - flags_needed = 'o'; Penalty = 0; syntax = "[<nick>] <channel>[,<channel>]"; + flags_needed = 'o'; syntax = "[<nick>] <channel>[,<channel>]"; TRANSLATE2(TR_NICK, TR_TEXT); } diff --git a/src/modules/m_sakick.cpp b/src/modules/m_sakick.cpp index ab168ca68..81a74502b 100644 --- a/src/modules/m_sakick.cpp +++ b/src/modules/m_sakick.cpp @@ -27,7 +27,7 @@ class CommandSakick : public Command public: CommandSakick(Module* Creator) : Command(Creator,"SAKICK", 2, 3) { - flags_needed = 'o'; Penalty = 0; syntax = "<channel> <nick> [reason]"; + flags_needed = 'o'; syntax = "<channel> <nick> [reason]"; TRANSLATE3(TR_TEXT, TR_NICK, TR_TEXT); } diff --git a/src/modules/m_samode.cpp b/src/modules/m_samode.cpp index bcb876d5b..394cea722 100644 --- a/src/modules/m_samode.cpp +++ b/src/modules/m_samode.cpp @@ -31,7 +31,7 @@ class CommandSamode : public Command CommandSamode(Module* Creator) : Command(Creator,"SAMODE", 2) { allow_empty_last_param = false; - flags_needed = 'o'; Penalty = 0; syntax = "<target> <modes> {<mode-parameters>}"; + flags_needed = 'o'; syntax = "<target> <modes> {<mode-parameters>}"; active = false; } @@ -96,7 +96,7 @@ class ModuleSaMode : public Module return MOD_RES_PASSTHRU; } - void Prioritize() + void Prioritize() CXX11_OVERRIDE { Module *override = ServerInstance->Modules->Find("m_override.so"); ServerInstance->Modules->SetPriority(this, I_OnPreMode, PRIORITY_BEFORE, override); diff --git a/src/modules/m_sanick.cpp b/src/modules/m_sanick.cpp index 3dc89b4f6..c9ceba78e 100644 --- a/src/modules/m_sanick.cpp +++ b/src/modules/m_sanick.cpp @@ -29,7 +29,7 @@ class CommandSanick : public Command CommandSanick(Module* Creator) : Command(Creator,"SANICK", 2) { allow_empty_last_param = false; - flags_needed = 'o'; Penalty = 0; syntax = "<nick> <new-nick>"; + flags_needed = 'o'; syntax = "<nick> <new-nick>"; TRANSLATE2(TR_NICK, TR_TEXT); } diff --git a/src/modules/m_sapart.cpp b/src/modules/m_sapart.cpp index db1e6fdee..b51316dc5 100644 --- a/src/modules/m_sapart.cpp +++ b/src/modules/m_sapart.cpp @@ -28,7 +28,7 @@ class CommandSapart : public Command public: CommandSapart(Module* Creator) : Command(Creator,"SAPART", 2, 3) { - flags_needed = 'o'; Penalty = 0; syntax = "<nick> <channel>[,<channel>] [reason]"; + flags_needed = 'o'; syntax = "<nick> <channel>[,<channel>] [reason]"; TRANSLATE3(TR_NICK, TR_TEXT, TR_TEXT); } diff --git a/src/modules/m_saquit.cpp b/src/modules/m_saquit.cpp index c3895ec12..9f700ec5f 100644 --- a/src/modules/m_saquit.cpp +++ b/src/modules/m_saquit.cpp @@ -28,7 +28,7 @@ class CommandSaquit : public Command public: CommandSaquit(Module* Creator) : Command(Creator, "SAQUIT", 2, 2) { - flags_needed = 'o'; Penalty = 0; syntax = "<nick> <reason>"; + flags_needed = 'o'; syntax = "<nick> <reason>"; TRANSLATE2(TR_NICK, TR_TEXT); } diff --git a/src/modules/m_sasl.cpp b/src/modules/m_sasl.cpp index 9cd81ae66..6ad9d77b7 100644 --- a/src/modules/m_sasl.cpp +++ b/src/modules/m_sasl.cpp @@ -153,10 +153,63 @@ class SaslAuthenticator SaslResult result; bool state_announced; + /* taken from m_services_account */ + static bool ReadCGIIRCExt(const char* extname, User* user, std::string& out) + { + ExtensionItem* wiext = ServerInstance->Extensions.GetItem(extname); + if (!wiext) + return false; + + if (wiext->creator->ModuleSourceFile != "m_cgiirc.so") + return false; + + StringExtItem* stringext = static_cast<StringExtItem*>(wiext); + std::string* addr = stringext->get(user); + if (!addr) + return false; + + out = *addr; + return true; + } + + + void SendHostIP() + { + std::string host, ip; + + if (!ReadCGIIRCExt("cgiirc_webirc_hostname", user, host)) + { + host = user->host; + } + if (!ReadCGIIRCExt("cgiirc_webirc_ip", user, ip)) + { + ip = user->GetIPString(); + } + else + { + /* IP addresses starting with a : on irc are a Bad Thing (tm) */ + if (ip.c_str()[0] == ':') + ip.insert(ip.begin(),1,'0'); + } + + parameterlist params; + params.push_back(sasl_target); + params.push_back("SASL"); + params.push_back(user->uuid); + params.push_back("*"); + params.push_back("H"); + params.push_back(host); + params.push_back(ip); + + SendSASL(params); + } + public: SaslAuthenticator(User* user_, const std::string& method) : user(user_), state(SASL_INIT), state_announced(false) { + SendHostIP(); + parameterlist params; params.push_back(user->uuid); params.push_back("*"); @@ -287,6 +340,7 @@ class CommandAuthenticate : public Command : Command(Creator, "AUTHENTICATE", 1), authExt(ext), cap(Cap) { works_before_reg = true; + allow_empty_last_param = false; } CmdResult Handle (const std::vector<std::string>& parameters, User *user) @@ -295,6 +349,9 @@ class CommandAuthenticate : public Command if (!cap.get(user)) return CMD_FAILURE; + if (parameters[0].find(' ') != std::string::npos || parameters[0][0] == ':') + return CMD_FAILURE; + SaslAuthenticator *sasl = authExt.get(user); if (!sasl) authExt.set(user, new SaslAuthenticator(user, parameters[0])); @@ -378,7 +435,7 @@ class ModuleSASL : public Module servertracker.Reset(); } - ModResult OnUserRegister(LocalUser *user) CXX11_OVERRIDE + void OnUserConnect(LocalUser *user) CXX11_OVERRIDE { SaslAuthenticator *sasl_ = authExt.get(user); if (sasl_) @@ -386,8 +443,6 @@ class ModuleSASL : public Module sasl_->Abort(); authExt.unset(user); } - - return MOD_RES_PASSTHRU; } void OnDecodeMetaData(Extensible* target, const std::string& extname, const std::string& extdata) CXX11_OVERRIDE diff --git a/src/modules/m_satopic.cpp b/src/modules/m_satopic.cpp index f966d6a5a..f45d9c8cd 100644 --- a/src/modules/m_satopic.cpp +++ b/src/modules/m_satopic.cpp @@ -26,7 +26,7 @@ class CommandSATopic : public Command public: CommandSATopic(Module* Creator) : Command(Creator,"SATOPIC", 2, 2) { - flags_needed = 'o'; Penalty = 0; syntax = "<target> <topic>"; + flags_needed = 'o'; syntax = "<target> <topic>"; } CmdResult Handle (const std::vector<std::string>& parameters, User *user) diff --git a/src/modules/m_sha1.cpp b/src/modules/m_sha1.cpp index 5926e4926..798539d91 100644 --- a/src/modules/m_sha1.cpp +++ b/src/modules/m_sha1.cpp @@ -190,7 +190,7 @@ class ModuleSHA1 : public Module big_endian = (htonl(1337) == 1337); } - Version GetVersion() + Version GetVersion() CXX11_OVERRIDE { return Version("Implements SHA-1 hashing", VF_VENDOR); } diff --git a/src/modules/m_shun.cpp b/src/modules/m_shun.cpp index 022726524..28faf898b 100644 --- a/src/modules/m_shun.cpp +++ b/src/modules/m_shun.cpp @@ -191,7 +191,7 @@ class ModuleShun : public Module ServerInstance->XLines->UnregisterFactory(&f); } - void Prioritize() + void Prioritize() CXX11_OVERRIDE { Module* alias = ServerInstance->Modules->Find("m_alias.so"); ServerInstance->Modules->SetPriority(this, I_OnPreCommand, PRIORITY_BEFORE, alias); diff --git a/src/modules/m_spanningtree/main.h b/src/modules/m_spanningtree/main.h index 46c21b4e9..00cbd3dcd 100644 --- a/src/modules/m_spanningtree/main.h +++ b/src/modules/m_spanningtree/main.h @@ -168,8 +168,8 @@ class ModuleSpanningTree : public Module void OnUnloadModule(Module* mod) CXX11_OVERRIDE; ModResult OnAcceptConnection(int newsock, ListenSocket* from, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server) CXX11_OVERRIDE; void OnMode(User* source, User* u, Channel* c, const Modes::ChangeList& modes, ModeParser::ModeProcessFlag processflags, const std::string& output_mode) CXX11_OVERRIDE; - CullResult cull(); + CullResult cull() CXX11_OVERRIDE; ~ModuleSpanningTree(); Version GetVersion() CXX11_OVERRIDE; - void Prioritize(); + void Prioritize() CXX11_OVERRIDE; }; diff --git a/src/modules/m_spanningtree/protocolinterface.h b/src/modules/m_spanningtree/protocolinterface.h index e7fed5475..b0609005c 100644 --- a/src/modules/m_spanningtree/protocolinterface.h +++ b/src/modules/m_spanningtree/protocolinterface.h @@ -37,7 +37,7 @@ class SpanningTreeProtocolInterface : public ProtocolInterface void SendMetaData(Channel* chan, const std::string& key, const std::string& data) CXX11_OVERRIDE; void SendMetaData(const std::string& key, const std::string& data) CXX11_OVERRIDE; void SendSNONotice(char snomask, const std::string& text) CXX11_OVERRIDE; - void SendMessage(Channel* target, char status, const std::string& text, MessageType msgtype); - void SendMessage(User* target, const std::string& text, MessageType msgtype); - void GetServerList(ServerList& sl); + void SendMessage(Channel* target, char status, const std::string& text, MessageType msgtype) CXX11_OVERRIDE; + void SendMessage(User* target, const std::string& text, MessageType msgtype) CXX11_OVERRIDE; + void GetServerList(ServerList& sl) CXX11_OVERRIDE; }; diff --git a/src/modules/m_spanningtree/servercommand.h b/src/modules/m_spanningtree/servercommand.h index 07dfc4898..ee7766764 100644 --- a/src/modules/m_spanningtree/servercommand.h +++ b/src/modules/m_spanningtree/servercommand.h @@ -43,7 +43,7 @@ class ServerCommand : public CommandBase void RegisterService() CXX11_OVERRIDE; virtual CmdResult Handle(User* user, std::vector<std::string>& parameters) = 0; - virtual RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters); + virtual RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters) CXX11_OVERRIDE; /** * Extract the TS from a string. diff --git a/src/modules/m_spanningtree/treeserver.h b/src/modules/m_spanningtree/treeserver.h index b7e9ee9d9..f75adf54c 100644 --- a/src/modules/m_spanningtree/treeserver.h +++ b/src/modules/m_spanningtree/treeserver.h @@ -219,7 +219,7 @@ class TreeServer : public Server */ void OnPong() { pingtimer.OnPong(); } - CullResult cull(); + CullResult cull() CXX11_OVERRIDE; /** Destructor, deletes ServerUser unless IsRoot() */ diff --git a/src/modules/m_spanningtree/treesocket.h b/src/modules/m_spanningtree/treesocket.h index 4887623c1..3571f2816 100644 --- a/src/modules/m_spanningtree/treesocket.h +++ b/src/modules/m_spanningtree/treesocket.h @@ -200,7 +200,7 @@ class TreeSocket : public BufferedSocket */ void CleanNegotiationInfo(); - CullResult cull(); + CullResult cull() CXX11_OVERRIDE; /** Destructor */ ~TreeSocket(); @@ -216,7 +216,7 @@ class TreeSocket : public BufferedSocket * to server docs on the inspircd.org site, the other side * will then send back its own server string. */ - void OnConnected(); + void OnConnected() CXX11_OVERRIDE; /** Handle socket error event */ @@ -270,7 +270,7 @@ class TreeSocket : public BufferedSocket /** This function is called when we receive data from a remote * server. */ - void OnDataReady(); + void OnDataReady() CXX11_OVERRIDE; /** Send one or more complete lines down the socket */ @@ -299,10 +299,10 @@ class TreeSocket : public BufferedSocket /** Handle socket timeout from connect() */ - void OnTimeout(); + void OnTimeout() CXX11_OVERRIDE; /** Handle server quit on close */ - void Close(); + void Close() CXX11_OVERRIDE; /** Fixes messages coming from old servers so the new command handlers understand them */ diff --git a/src/modules/m_spanningtree/uid.cpp b/src/modules/m_spanningtree/uid.cpp index a41fe408d..91c9f3ca8 100644 --- a/src/modules/m_spanningtree/uid.cpp +++ b/src/modules/m_spanningtree/uid.cpp @@ -50,12 +50,8 @@ CmdResult CommandUID::HandleServer(TreeServer* remoteserver, std::vector<std::st { // User that the incoming user is colliding with is not fully registered, we force nick change the // unregistered user to their uuid and tell them what happened - collideswith->WriteFrom(collideswith, "NICK %s", collideswith->uuid.c_str()); - collideswith->WriteNumeric(ERR_NICKNAMEINUSE, collideswith->nick, "Nickname overruled."); - - // Clear the bit before calling User::ChangeNick() to make it NOT run the OnUserPostNick() hook - collideswith->registered &= ~REG_NICK; - collideswith->ChangeNick(collideswith->uuid); + LocalUser* const localuser = static_cast<LocalUser*>(collideswith); + localuser->OverruleNick(); } else if (collideswith) { @@ -166,6 +162,6 @@ CommandUID::Builder::Builder(User* user) push(user->ident); push(user->GetIPString()); push_int(user->signon); - push('+').push_raw(user->FormatModes(true)); + push(user->GetModeLetters(true)); push_last(user->fullname); } diff --git a/src/modules/m_spanningtree/utils.h b/src/modules/m_spanningtree/utils.h index a2f7212f6..f262f9a48 100644 --- a/src/modules/m_spanningtree/utils.h +++ b/src/modules/m_spanningtree/utils.h @@ -108,7 +108,7 @@ class SpanningTreeUtilities : public classbase /** Prepare for class destruction */ - CullResult cull(); + CullResult cull() CXX11_OVERRIDE; /** Destroy class and free listeners etc */ diff --git a/src/modules/m_timedbans.cpp b/src/modules/m_timedbans.cpp index 874e6440f..44c6c4c4f 100644 --- a/src/modules/m_timedbans.cpp +++ b/src/modules/m_timedbans.cpp @@ -218,7 +218,7 @@ class ModuleTimedBans : public Module } } - void OnChannelDelete(Channel* chan) + void OnChannelDelete(Channel* chan) CXX11_OVERRIDE { // Remove all timed bans affecting the channel from internal bookkeeping TimedBanList.erase(std::remove_if(TimedBanList.begin(), TimedBanList.end(), ChannelMatcher(chan)), TimedBanList.end()); diff --git a/src/socketengine.cpp b/src/socketengine.cpp index 4183488b7..3735e7530 100644 --- a/src/socketengine.cpp +++ b/src/socketengine.cpp @@ -203,40 +203,35 @@ void SocketEngine::SetReuse(int fd) int SocketEngine::RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, sockaddr *from, socklen_t *fromlen) { int nbRecvd = recvfrom(fd->GetFd(), (char*)buf, len, flags, from, fromlen); - if (nbRecvd > 0) - stats.Update(nbRecvd, 0); + stats.UpdateReadCounters(nbRecvd); return nbRecvd; } int SocketEngine::Send(EventHandler* fd, const void *buf, size_t len, int flags) { int nbSent = send(fd->GetFd(), (const char*)buf, len, flags); - if (nbSent > 0) - stats.Update(0, nbSent); + stats.UpdateWriteCounters(nbSent); return nbSent; } int SocketEngine::Recv(EventHandler* fd, void *buf, size_t len, int flags) { int nbRecvd = recv(fd->GetFd(), (char*)buf, len, flags); - if (nbRecvd > 0) - stats.Update(nbRecvd, 0); + stats.UpdateReadCounters(nbRecvd); return nbRecvd; } int SocketEngine::SendTo(EventHandler* fd, const void *buf, size_t len, int flags, const sockaddr *to, socklen_t tolen) { int nbSent = sendto(fd->GetFd(), (const char*)buf, len, flags, to, tolen); - if (nbSent > 0) - stats.Update(0, nbSent); + stats.UpdateWriteCounters(nbSent); return nbSent; } int SocketEngine::WriteV(EventHandler* fd, const IOVector* iovec, int count) { int sent = writev(fd->GetFd(), iovec, count); - if (sent > 0) - stats.Update(0, sent); + stats.UpdateWriteCounters(sent); return sent; } @@ -289,11 +284,26 @@ int SocketEngine::Shutdown(int fd, int how) return shutdown(fd, how); } -void SocketEngine::Statistics::Update(size_t len_in, size_t len_out) +void SocketEngine::Statistics::UpdateReadCounters(int len_in) { CheckFlush(); - indata += len_in; - outdata += len_out; + + ReadEvents++; + if (len_in > 0) + indata += len_in; + else if (len_in < 0) + ErrorEvents++; +} + +void SocketEngine::Statistics::UpdateWriteCounters(int len_out) +{ + CheckFlush(); + + WriteEvents++; + if (len_out > 0) + outdata += len_out; + else if (len_out < 0) + ErrorEvents++; } void SocketEngine::Statistics::CheckFlush() const diff --git a/src/socketengines/socketengine_epoll.cpp b/src/socketengines/socketengine_epoll.cpp index 7602dd201..c442e340d 100644 --- a/src/socketengines/socketengine_epoll.cpp +++ b/src/socketengines/socketengine_epoll.cpp @@ -22,7 +22,7 @@ #include "exitcodes.h" #include <sys/epoll.h> -#include <ulimit.h> +#include <sys/resource.h> #include <iostream> /** A specialisation of the SocketEngine class, designed to use linux 2.6 epoll(). @@ -38,8 +38,12 @@ namespace void SocketEngine::Init() { - // MAX_DESCRIPTORS is mainly used for display purposes, no problem if ulimit() fails and returns a negative number - MAX_DESCRIPTORS = ulimit(4, 0); + // MAX_DESCRIPTORS is mainly used for display purposes, no problem if getrlimit() fails + struct rlimit limit; + if (!getrlimit(RLIMIT_NOFILE, &limit)) + { + MAX_DESCRIPTORS = limit.rlim_cur; + } // 128 is not a maximum, just a hint at the eventual number of sockets that may be polled, // and it is completely ignored by 2.6.8 and later kernels, except it must be larger than zero. @@ -213,7 +217,6 @@ int SocketEngine::DispatchEvents() eh->SetEventMask(mask); if (ev.events & EPOLLIN) { - stats.ReadEvents++; eh->OnEventHandlerRead(); if (eh != GetRef(fd)) // whoa! we got deleted, better not give out the write event @@ -221,7 +224,6 @@ int SocketEngine::DispatchEvents() } if (ev.events & EPOLLOUT) { - stats.WriteEvents++; eh->OnEventHandlerWrite(); } } diff --git a/src/socketengines/socketengine_kqueue.cpp b/src/socketengines/socketengine_kqueue.cpp index 922cb7f2d..9db902314 100644 --- a/src/socketengines/socketengine_kqueue.cpp +++ b/src/socketengines/socketengine_kqueue.cpp @@ -199,7 +199,6 @@ int SocketEngine::DispatchEvents() } if (filter == EVFILT_WRITE) { - stats.WriteEvents++; /* When mask is FD_WANT_FAST_WRITE or FD_WANT_SINGLE_WRITE, * we set a one-shot write, so we need to clear that bit * to detect when it set again. @@ -210,7 +209,6 @@ int SocketEngine::DispatchEvents() } else if (filter == EVFILT_READ) { - stats.ReadEvents++; eh->SetEventMask(eh->GetEventMask() & ~FD_READ_WILL_BLOCK); eh->OnEventHandlerRead(); } diff --git a/src/socketengines/socketengine_ports.cpp b/src/socketengines/socketengine_ports.cpp index d94d02664..68fa70e3b 100644 --- a/src/socketengines/socketengine_ports.cpp +++ b/src/socketengines/socketengine_ports.cpp @@ -159,14 +159,12 @@ int SocketEngine::DispatchEvents() port_associate(EngineHandle, PORT_SOURCE_FD, fd, mask_to_events(mask), eh); if (portev_events & POLLRDNORM) { - stats.ReadEvents++; eh->OnEventHandlerRead(); if (eh != GetRef(fd)) continue; } if (portev_events & POLLWRNORM) { - stats.WriteEvents++; eh->OnEventHandlerWrite(); } } diff --git a/src/socketengines/socketengine_select.cpp b/src/socketengines/socketengine_select.cpp index 6dfbae88e..42f634db1 100644 --- a/src/socketengines/socketengine_select.cpp +++ b/src/socketengines/socketengine_select.cpp @@ -147,7 +147,6 @@ int SocketEngine::DispatchEvents() if (has_read) { - stats.ReadEvents++; ev->SetEventMask(ev->GetEventMask() & ~FD_READ_WILL_BLOCK); ev->OnEventHandlerRead(); if (ev != GetRef(i)) @@ -156,7 +155,6 @@ int SocketEngine::DispatchEvents() if (has_write) { - stats.WriteEvents++; int newmask = (ev->GetEventMask() & ~(FD_WRITE_WILL_BLOCK | FD_WANT_SINGLE_WRITE)); SocketEngine::OnSetEvent(ev, ev->GetEventMask(), newmask); ev->SetEventMask(newmask); diff --git a/src/users.cpp b/src/users.cpp index 498a27d58..d54931644 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -33,34 +33,34 @@ bool User::IsNoticeMaskSet(unsigned char sm) return (snomasks[sm-65]); } -bool User::IsModeSet(unsigned char m) +bool User::IsModeSet(unsigned char m) const { ModeHandler* mh = ServerInstance->Modes->FindMode(m, MODETYPE_USER); return (mh && modes[mh->GetId()]); } -const char* User::FormatModes(bool showparameters) +std::string User::GetModeLetters(bool includeparams) const { - static std::string data; + std::string ret(1, '+'); std::string params; - data.clear(); - for (unsigned char n = 0; n < 64; n++) + for (unsigned char i = 'A'; i < 'z'; i++) { - ModeHandler* mh = ServerInstance->Modes->FindMode(n + 65, MODETYPE_USER); - if (mh && IsModeSet(mh)) + const ModeHandler* const mh = ServerInstance->Modes.FindMode(i, MODETYPE_USER); + if ((!mh) || (!IsModeSet(mh))) + continue; + + ret.push_back(mh->GetModeChar()); + if ((includeparams) && (mh->NeedsParam(true))) { - data.push_back(n + 65); - if (showparameters && mh->NeedsParam(true)) - { - std::string p = mh->GetUserParameter(this); - if (p.length()) - params.append(" ").append(p); - } + const std::string val = mh->GetUserParameter(this); + if (!val.empty()) + params.append(1, ' ').append(val); } } - data += params; - return data.c_str(); + + ret += params; + return ret; } User::User(const std::string& uid, Server* srv, int type) @@ -588,6 +588,7 @@ void LocalUser::FullConnect() void User::InvalidateCache() { /* Invalidate cache */ + cachedip.clear(); cached_fullhost.clear(); cached_hostip.clear(); cached_makehost.clear(); @@ -627,11 +628,8 @@ bool User::ChangeNick(const std::string& newnick, time_t newts) if (InUse->registered != REG_ALL) { /* force the camper to their UUID, and ask them to re-send a NICK. */ - InUse->WriteFrom(InUse, "NICK %s", InUse->uuid.c_str()); - InUse->WriteNumeric(ERR_NICKNAMEINUSE, InUse->nick, "Nickname overruled."); - - InUse->registered &= ~REG_NICK; - InUse->ChangeNick(InUse->uuid); + LocalUser* const localuser = static_cast<LocalUser*>(InUse); + localuser->OverruleNick(); } else { @@ -659,6 +657,16 @@ bool User::ChangeNick(const std::string& newnick, time_t newts) return true; } +void LocalUser::OverruleNick() +{ + this->WriteFrom(this, "NICK %s", this->uuid.c_str()); + this->WriteNumeric(ERR_NICKNAMEINUSE, this->nick, "Nickname overruled."); + + // Clear the bit before calling ChangeNick() to make it NOT run the OnUserPostNick() hook + this->registered &= ~REG_NICK; + this->ChangeNick(this->uuid); +} + int LocalUser::GetServerPort() { switch (this->server_sa.sa.sa_family) @@ -702,8 +710,7 @@ irc::sockets::cidr_mask User::GetCIDRMask() bool User::SetClientIP(const char* sip, bool recheck_eline) { - cachedip.clear(); - cached_hostip.clear(); + this->InvalidateCache(); return irc::sockets::aptosa(sip, 0, client_sa); } |