diff options
Diffstat (limited to 'src/modules')
-rw-r--r-- | src/modules/m_alias.cpp | 22 | ||||
-rw-r--r-- | src/modules/m_censor.cpp | 7 | ||||
-rw-r--r-- | src/modules/m_chanlog.cpp | 9 | ||||
-rw-r--r-- | src/modules/m_customtitle.cpp | 89 | ||||
-rw-r--r-- | src/modules/m_dccallow.cpp | 26 | ||||
-rw-r--r-- | src/modules/m_dnsbl.cpp | 22 | ||||
-rw-r--r-- | src/modules/m_flashpolicyd.cpp | 7 | ||||
-rw-r--r-- | src/modules/m_hidelist.cpp | 15 | ||||
-rw-r--r-- | src/modules/m_hidemode.cpp | 20 | ||||
-rw-r--r-- | src/modules/m_httpd_acl.cpp | 5 | ||||
-rw-r--r-- | src/modules/m_inviteexception.cpp | 2 | ||||
-rw-r--r-- | src/modules/m_pbkdf2.cpp | 58 | ||||
-rw-r--r-- | src/modules/m_restrictchans.cpp | 15 | ||||
-rw-r--r-- | src/modules/m_securelist.cpp | 15 | ||||
-rw-r--r-- | src/modules/m_vhost.cpp | 82 |
15 files changed, 276 insertions, 118 deletions
diff --git a/src/modules/m_alias.cpp b/src/modules/m_alias.cpp index 6f27ecc09..4d1dd65c9 100644 --- a/src/modules/m_alias.cpp +++ b/src/modules/m_alias.cpp @@ -74,27 +74,35 @@ class ModuleAlias : public Module public: void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE { - ConfigTag* fantasy = ServerInstance->Config->ConfValue("fantasy"); - AllowBots = fantasy->getBool("allowbots", false); - fprefix = fantasy->getString("prefix", "!", 1, ServerInstance->Config->Limits.MaxLine); - - Aliases.clear(); + AliasMap newAliases; ConfigTagList tags = ServerInstance->Config->ConfTags("alias"); for(ConfigIter i = tags.first; i != tags.second; ++i) { ConfigTag* tag = i->second; Alias a; a.AliasedCommand = tag->getString("text"); - std::transform(a.AliasedCommand.begin(), a.AliasedCommand.end(), a.AliasedCommand.begin(), ::toupper); + if (a.AliasedCommand.empty()) + throw ModuleException("<alias:text> is empty! at " + tag->getTagLocation()); + tag->readString("replace", a.ReplaceFormat, true); + if (a.ReplaceFormat.empty()) + throw ModuleException("<alias:replace> is empty! at " + tag->getTagLocation()); + a.RequiredNick = tag->getString("requires"); a.ULineOnly = tag->getBool("uline"); a.ChannelCommand = tag->getBool("channelcommand", false); a.UserCommand = tag->getBool("usercommand", true); a.OperOnly = tag->getBool("operonly"); a.format = tag->getString("format"); - Aliases.insert(std::make_pair(a.AliasedCommand, a)); + + std::transform(a.AliasedCommand.begin(), a.AliasedCommand.end(), a.AliasedCommand.begin(), ::toupper); + newAliases.insert(std::make_pair(a.AliasedCommand, a)); } + + ConfigTag* fantasy = ServerInstance->Config->ConfValue("fantasy"); + AllowBots = fantasy->getBool("allowbots", false); + fprefix = fantasy->getString("prefix", "!", 1, ServerInstance->Config->Limits.MaxLine); + Aliases.swap(newAliases); } ModuleAlias() diff --git a/src/modules/m_censor.cpp b/src/modules/m_censor.cpp index a9c55386c..31309ed2f 100644 --- a/src/modules/m_censor.cpp +++ b/src/modules/m_censor.cpp @@ -104,7 +104,7 @@ class ModuleCensor : public Module * reload our config file on rehash - we must destroy and re-allocate the classes * to call the constructor again and re-read our data. */ - censors.clear(); + censor_t newcensors; ConfigTagList badwords = ServerInstance->Config->ConfTags("badword"); for (ConfigIter i = badwords.first; i != badwords.second; ++i) @@ -112,11 +112,12 @@ class ModuleCensor : public Module ConfigTag* tag = i->second; const std::string text = tag->getString("text"); if (text.empty()) - continue; + throw ModuleException("<badword:text> is empty! at " + tag->getTagLocation()); const std::string replace = tag->getString("replace"); - censors[text] = replace; + newcensors[text] = replace; } + censors.swap(newcensors); } Version GetVersion() CXX11_OVERRIDE diff --git a/src/modules/m_chanlog.cpp b/src/modules/m_chanlog.cpp index 85e7ca2eb..afe213f61 100644 --- a/src/modules/m_chanlog.cpp +++ b/src/modules/m_chanlog.cpp @@ -33,8 +33,7 @@ class ModuleChanLog : public Module { std::string snomasks; std::string channel; - - logstreams.clear(); + ChanLogTargets newlogs; ConfigTagList tags = ServerInstance->Config->ConfTags("chanlog"); for (ConfigIter i = tags.first; i != tags.second; ++i) @@ -44,16 +43,16 @@ class ModuleChanLog : public Module if (channel.empty() || snomasks.empty()) { - ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Malformed chanlog tag, ignoring"); - continue; + throw ModuleException("Malformed chanlog tag at " + i->second->getTagLocation()); } for (std::string::const_iterator it = snomasks.begin(); it != snomasks.end(); it++) { - logstreams.insert(std::make_pair(*it, channel)); + newlogs.insert(std::make_pair(*it, channel)); ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Logging %c to %s", *it, channel.c_str()); } } + logstreams.swap(newlogs); } diff --git a/src/modules/m_customtitle.cpp b/src/modules/m_customtitle.cpp index c16b1eda2..2dd378062 100644 --- a/src/modules/m_customtitle.cpp +++ b/src/modules/m_customtitle.cpp @@ -28,12 +28,49 @@ enum RPL_WHOISSPECIAL = 320 }; +struct CustomTitle +{ + const std::string name; + const std::string password; + const std::string hash; + const std::string host; + const std::string title; + const std::string vhost; + + CustomTitle(const std::string& n, const std::string& p, const std::string& h, const std::string& hst, const std::string& t, const std::string& v) + : name(n) + , password(p) + , hash(h) + , host(hst) + , title(t) + , vhost(v) + { + } + + bool MatchUser(User* user) const + { + const std::string userHost = user->ident + "@" + user->GetRealHost(); + const std::string userIP = user->ident + "@" + user->GetIPString(); + return InspIRCd::MatchMask(host, userHost, userIP); + } + + bool CheckPass(User* user, const std::string& pass) const + { + return ServerInstance->PassCompare(user, password, pass, hash); + } +}; + +typedef std::multimap<std::string, CustomTitle> CustomVhostMap; +typedef std::pair<CustomVhostMap::iterator, CustomVhostMap::iterator> MatchingConfigs; + /** Handle /TITLE */ class CommandTitle : public Command { public: StringExtItem ctitle; + CustomVhostMap configs; + CommandTitle(Module* Creator) : Command(Creator,"TITLE", 2), ctitle("ctitle", ExtensionItem::EXT_USER, Creator) { @@ -42,30 +79,21 @@ class CommandTitle : public Command CmdResult Handle(User* user, const Params& parameters) CXX11_OVERRIDE { - const std::string userHost = user->ident + "@" + user->GetRealHost(); - const std::string userIP = user->ident + "@" + user->GetIPString(); + MatchingConfigs matching = configs.equal_range(parameters[0]); - ConfigTagList tags = ServerInstance->Config->ConfTags("title"); - for (ConfigIter i = tags.first; i != tags.second; ++i) + for (MatchingConfigs::first_type i = matching.first; i != matching.second; ++i) { - std::string Name = i->second->getString("name"); - std::string pass = i->second->getString("password"); - std::string hash = i->second->getString("hash"); - std::string host = i->second->getString("host", "*@*"); - std::string title = i->second->getString("title"); - std::string vhost = i->second->getString("vhost"); - - if (Name == parameters[0] && ServerInstance->PassCompare(user, pass, parameters[1], hash) && - InspIRCd::MatchMask(host, userHost, userIP) && !title.empty()) + CustomTitle config = i->second; + if (config.MatchUser(user) && config.CheckPass(user, parameters[1])) { - ctitle.set(user, title); + ctitle.set(user, config.title); - ServerInstance->PI->SendMetaData(user, "ctitle", title); + ServerInstance->PI->SendMetaData(user, "ctitle", config.title); - if (!vhost.empty()) - user->ChangeDisplayedHost(vhost); + if (!config.vhost.empty()) + user->ChangeDisplayedHost(config.vhost); - user->WriteNotice("Custom title set to '" + title + "'"); + user->WriteNotice("Custom title set to '" + config.title + "'"); return CMD_SUCCESS; } @@ -88,6 +116,31 @@ class ModuleCustomTitle : public Module, public Whois::LineEventListener { } + void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE + { + ConfigTagList tags = ServerInstance->Config->ConfTags("title"); + CustomVhostMap newtitles; + for (ConfigIter i = tags.first; i != tags.second; ++i) + { + reference<ConfigTag> tag = i->second; + std::string name = tag->getString("name", "", 1); + if (name.empty()) + throw ModuleException("<title:name> is empty at " + tag->getTagLocation()); + + std::string pass = tag->getString("password"); + if (pass.empty()) + throw ModuleException("<title:password> is empty at " + tag->getTagLocation()); + + std::string hash = tag->getString("hash"); + std::string host = tag->getString("host", "*@*"); + std::string title = tag->getString("title"); + std::string vhost = tag->getString("vhost"); + CustomTitle config(name, pass, hash, host, title, vhost); + newtitles.insert(std::make_pair(name, config)); + } + cmd.configs.swap(newtitles); + } + // :kenny.chatspike.net 320 Brain Azhrarn :is getting paid to play games. ModResult OnWhoisLine(Whois::Context& whois, Numeric::Numeric& numeric) CXX11_OVERRIDE { diff --git a/src/modules/m_dccallow.cpp b/src/modules/m_dccallow.cpp index eb364089a..85f9d20d0 100644 --- a/src/modules/m_dccallow.cpp +++ b/src/modules/m_dccallow.cpp @@ -106,6 +106,7 @@ class CommandDccallow : public Command public: unsigned int maxentries; + unsigned long defaultlength; CommandDccallow(Module* parent, DCCAllowExt& Ext) : Command(parent, "DCCALLOW", 0) , ext(Ext) @@ -206,12 +207,10 @@ class CommandDccallow : public Command } std::string mask = target->nick+"!"+target->ident+"@"+target->GetDisplayedHost(); - std::string default_length = ServerInstance->Config->ConfValue("dccallow")->getString("length"); - unsigned long length; if (parameters.size() < 2) { - length = InspIRCd::Duration(default_length); + length = defaultlength; } else if (!InspIRCd::IsValidDuration(parameters[1])) { @@ -293,11 +292,14 @@ class ModuleDCCAllow : public Module { DCCAllowExt ext; CommandDccallow cmd; + bool blockchat; + std::string defaultaction; public: ModuleDCCAllow() : ext("dccallow", ExtensionItem::EXT_USER, this) , cmd(this, ext) + , blockchat(false) { } @@ -356,9 +358,6 @@ class ModuleDCCAllow : public Module const std::string type = buf.substr(0, s); - ConfigTag* conftag = ServerInstance->Config->ConfValue("dccallow"); - bool blockchat = conftag->getBool("blockchat"); - if (stdalgo::string::equalsci(type, "SEND")) { size_t first; @@ -384,7 +383,6 @@ class ModuleDCCAllow : public Module if (s == std::string::npos) return MOD_RES_PASSTHRU; - std::string defaultaction = conftag->getString("action"); std::string filename = buf.substr(first, s); bool found = false; @@ -507,18 +505,22 @@ class ModuleDCCAllow : public Module void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE { - ConfigTag* tag = ServerInstance->Config->ConfValue("dccallow"); - cmd.maxentries = tag->getUInt("maxentries", 20); - - bfl.clear(); + bannedfilelist newbfl; ConfigTagList tags = ServerInstance->Config->ConfTags("banfile"); for (ConfigIter i = tags.first; i != tags.second; ++i) { BannedFileList bf; bf.filemask = i->second->getString("pattern"); bf.action = i->second->getString("action"); - bfl.push_back(bf); + newbfl.push_back(bf); } + bfl.swap(newbfl); + + ConfigTag* tag = ServerInstance->Config->ConfValue("dccallow"); + cmd.maxentries = tag->getUInt("maxentries", 20); + cmd.defaultlength = tag->getDuration("length", 0); + blockchat = tag->getBool("blockchat"); + defaultaction = tag->getString("action"); } Version GetVersion() CXX11_OVERRIDE diff --git a/src/modules/m_dnsbl.cpp b/src/modules/m_dnsbl.cpp index 7b88bc961..d1ca800b3 100644 --- a/src/modules/m_dnsbl.cpp +++ b/src/modules/m_dnsbl.cpp @@ -228,9 +228,11 @@ class DNSBLResolver : public DNS::Request } }; +typedef std::vector<reference<DNSBLConfEntry> > DNSBLConfList; + class ModuleDNSBL : public Module, public Stats::EventListener { - std::vector<reference<DNSBLConfEntry> > DNSBLConfEntries; + DNSBLConfList DNSBLConfEntries; dynamic_reference<DNS::Manager> DNS; LocalStringExt nameExt; LocalIntExt countExt; @@ -276,7 +278,7 @@ class ModuleDNSBL : public Module, public Stats::EventListener */ void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE { - DNSBLConfEntries.clear(); + DNSBLConfList newentries; ConfigTagList dnsbls = ServerInstance->Config->ConfTags("dnsbl"); for(ConfigIter i = dnsbls.first; i != dnsbls.second; ++i) @@ -313,23 +315,19 @@ class ModuleDNSBL : public Module, public Stats::EventListener /* yeah, logic here is a little messy */ if ((e->bitmask <= 0) && (DNSBLConfEntry::A_BITMASK == e->type)) { - std::string location = tag->getTagLocation(); - ServerInstance->SNO->WriteGlobalSno('d', "DNSBL(%s): invalid bitmask", location.c_str()); + throw ModuleException("Invalid <dnsbl:bitmask> at " + tag->getTagLocation()); } else if (e->name.empty()) { - std::string location = tag->getTagLocation(); - ServerInstance->SNO->WriteGlobalSno('d', "DNSBL(%s): Invalid name", location.c_str()); + throw ModuleException("Empty <dnsbl:name> at " + tag->getTagLocation()); } else if (e->domain.empty()) { - std::string location = tag->getTagLocation(); - ServerInstance->SNO->WriteGlobalSno('d', "DNSBL(%s): Invalid domain", location.c_str()); + throw ModuleException("Empty <dnsbl:domain> at " + tag->getTagLocation()); } else if (e->banaction == DNSBLConfEntry::I_UNKNOWN) { - std::string location = tag->getTagLocation(); - ServerInstance->SNO->WriteGlobalSno('d', "DNSBL(%s): Invalid banaction", location.c_str()); + throw ModuleException("Unknown <dnsbl:action> at " + tag->getTagLocation()); } else { @@ -341,9 +339,11 @@ class ModuleDNSBL : public Module, public Stats::EventListener } /* add it, all is ok */ - DNSBLConfEntries.push_back(e); + newentries.push_back(e); } } + + DNSBLConfEntries.swap(newentries); } void OnSetUserIP(LocalUser* user) CXX11_OVERRIDE diff --git a/src/modules/m_flashpolicyd.cpp b/src/modules/m_flashpolicyd.cpp index d7f9a793b..db0eeb1f1 100644 --- a/src/modules/m_flashpolicyd.cpp +++ b/src/modules/m_flashpolicyd.cpp @@ -97,7 +97,6 @@ class ModuleFlashPD : public Module void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE { ConfigTag* tag = ServerInstance->Config->ConfValue("flashpolicyd"); - timeout = tag->getDuration("timeout", 5, 1); std::string file = tag->getString("file"); if (!file.empty()) @@ -109,10 +108,7 @@ class ModuleFlashPD : public Module } catch (CoreException&) { - const std::string error_message = "A file was specified for FlashPD, but it could not be loaded."; - ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, error_message); - ServerInstance->SNO->WriteGlobalSno('a', error_message); - policy_reply.clear(); + throw ModuleException("A file was specified for FlashPD, but it could not be loaded at " + tag->getTagLocation()); } return; } @@ -144,6 +140,7 @@ class ModuleFlashPD : public Module <site-control permitted-cross-domain-policies=\"master-only\"/>\ <allow-access-from domain=\"*\" to-ports=\"" + to_ports + "\" />\ </cross-domain-policy>"; + timeout = tag->getDuration("timeout", 5, 1); } CullResult cull() CXX11_OVERRIDE diff --git a/src/modules/m_hidelist.cpp b/src/modules/m_hidelist.cpp index 2d3f0be7c..9c8811fb8 100644 --- a/src/modules/m_hidelist.cpp +++ b/src/modules/m_hidelist.cpp @@ -58,19 +58,26 @@ class ModuleHideList : public Module public: void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE { - stdalgo::delete_all(watchers); - watchers.clear(); - ConfigTagList tags = ServerInstance->Config->ConfTags("hidelist"); + typedef std::vector<std::pair<std::string, unsigned int> > NewConfigs; + NewConfigs newconfigs; for (ConfigIter i = tags.first; i != tags.second; ++i) { ConfigTag* tag = i->second; std::string modename = tag->getString("mode"); + if (modename.empty()) + throw ModuleException("Empty <hidelist:mode> at " + tag->getTagLocation()); // If rank is set to 0 everyone inside the channel can view the list, // but non-members may not unsigned int rank = tag->getUInt("rank", HALFOP_VALUE); - watchers.push_back(new ListWatcher(this, modename, rank)); + newconfigs.push_back(std::make_pair(modename, rank)); } + + stdalgo::delete_all(watchers); + watchers.clear(); + + for (NewConfigs::const_iterator i = newconfigs.begin(); i != newconfigs.end(); ++i) + watchers.push_back(new ListWatcher(this, i->first, i->second)); } ~ModuleHideList() diff --git a/src/modules/m_hidemode.cpp b/src/modules/m_hidemode.cpp index d6ae05801..d5ac57115 100644 --- a/src/modules/m_hidemode.cpp +++ b/src/modules/m_hidemode.cpp @@ -37,20 +37,24 @@ class Settings void Load() { - rankstosee.clear(); + RanksToSeeMap newranks; ConfigTagList tags = ServerInstance->Config->ConfTags("hidemode"); for (ConfigIter i = tags.first; i != tags.second; ++i) { ConfigTag* tag = i->second; - std::string modename = tag->getString("mode"); - unsigned int rank = tag->getInt("rank", 0, 0); - if (!modename.empty() && rank) - { - ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Hiding the %s mode from users below rank %u", modename.c_str(), rank); - rankstosee.insert(std::make_pair(modename, rank)); - } + const std::string modename = tag->getString("mode"); + if (modename.empty()) + throw ModuleException("<hidemode:mode> is empty at " + tag->getTagLocation()); + + unsigned int rank = tag->getUInt("rank", 0); + if (!rank) + throw ModuleException("<hidemode:rank> must be greater than 0 at " + tag->getTagLocation()); + + ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Hiding the %s mode from users below rank %u", modename.c_str(), rank); + newranks.insert(std::make_pair(modename, rank)); } + rankstosee.swap(newranks); } }; diff --git a/src/modules/m_httpd_acl.cpp b/src/modules/m_httpd_acl.cpp index 2dbc1be69..49710c219 100644 --- a/src/modules/m_httpd_acl.cpp +++ b/src/modules/m_httpd_acl.cpp @@ -51,7 +51,7 @@ class ModuleHTTPAccessList : public Module, public HTTPACLEventListener void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE { - acl_list.clear(); + std::vector<HTTPACL> new_acls; ConfigTagList acls = ServerInstance->Config->ConfTags("httpdacl"); for (ConfigIter i = acls.first; i != acls.second; i++) { @@ -89,8 +89,9 @@ class ModuleHTTPAccessList : public Module, public HTTPACLEventListener ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Read ACL: path=%s pass=%s whitelist=%s blacklist=%s", path.c_str(), password.c_str(), whitelist.c_str(), blacklist.c_str()); - acl_list.push_back(HTTPACL(path, username, password, whitelist, blacklist)); + new_acls.push_back(HTTPACL(path, username, password, whitelist, blacklist)); } + acl_list.swap(new_acls); } void BlockAccess(HTTPRequest* http, unsigned int returnval, const std::string &extraheaderkey = "", const std::string &extraheaderval="") diff --git a/src/modules/m_inviteexception.cpp b/src/modules/m_inviteexception.cpp index 1317e6e57..bae8f7184 100644 --- a/src/modules/m_inviteexception.cpp +++ b/src/modules/m_inviteexception.cpp @@ -82,8 +82,8 @@ public: void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE { - invite_bypass_key = ServerInstance->Config->ConfValue("inviteexception")->getBool("bypasskey", true); ie.DoRehash(); + invite_bypass_key = ServerInstance->Config->ConfValue("inviteexception")->getBool("bypasskey", true); } Version GetVersion() CXX11_OVERRIDE diff --git a/src/modules/m_pbkdf2.cpp b/src/modules/m_pbkdf2.cpp index 86530c5dd..036538a39 100644 --- a/src/modules/m_pbkdf2.cpp +++ b/src/modules/m_pbkdf2.cpp @@ -139,39 +139,65 @@ class PBKDF2Provider : public HashProvider } }; +struct ProviderConfig +{ + unsigned long dkey_length; + unsigned long iterations; +}; + +typedef std::map<std::string, ProviderConfig> ProviderConfigMap; + class ModulePBKDF2 : public Module { std::vector<PBKDF2Provider*> providers; + ProviderConfig globalconfig; + ProviderConfigMap providerconfigs; - void GetConfig() + ProviderConfig GetConfigForProvider(const std::string& name) const + { + ProviderConfigMap::const_iterator it = providerconfigs.find(name); + if (it == providerconfigs.end()) + return globalconfig; + + return it->second; + } + + void ConfigureProviders() { - // First set the common values - ConfigTag* tag = ServerInstance->Config->ConfValue("pbkdf2"); - unsigned int global_iterations = tag->getUInt("iterations", 12288, 1); - unsigned int global_dkey_length = tag->getUInt("length", 32, 1, 1024); for (std::vector<PBKDF2Provider*>::iterator i = providers.begin(); i != providers.end(); ++i) { PBKDF2Provider* pi = *i; - pi->iterations = global_iterations; - pi->dkey_length = global_dkey_length; + ProviderConfig config = GetConfigForProvider(pi->name); + pi->iterations = config.iterations; + pi->dkey_length = config.dkey_length; } + } + + void GetConfig() + { + // First set the common values + ConfigTag* tag = ServerInstance->Config->ConfValue("pbkdf2"); + ProviderConfig newglobal; + newglobal.iterations = tag->getUInt("iterations", 12288, 1); + newglobal.dkey_length = tag->getUInt("length", 32, 1, 1024); // Then the specific values + ProviderConfigMap newconfigs; ConfigTagList tags = ServerInstance->Config->ConfTags("pbkdf2prov"); for (ConfigIter i = tags.first; i != tags.second; ++i) { tag = i->second; std::string hash_name = "hash/" + tag->getString("hash"); - for (std::vector<PBKDF2Provider*>::iterator j = providers.begin(); j != providers.end(); ++j) - { - PBKDF2Provider* pi = *j; - if (pi->provider->name != hash_name) - continue; + ProviderConfig& config = newconfigs[hash_name]; - pi->iterations = tag->getUInt("iterations", global_iterations, 1); - pi->dkey_length = tag->getUInt("length", global_dkey_length, 1, 1024); - } + config.iterations = tag->getUInt("iterations", newglobal.iterations, 1); + config.dkey_length = tag->getUInt("length", newglobal.dkey_length, 1, 1024); } + + // Config is valid, apply it + providerconfigs.swap(newconfigs); + std::swap(globalconfig, newglobal); + ConfigureProviders(); } public: @@ -194,7 +220,7 @@ class ModulePBKDF2 : public Module providers.push_back(prov); ServerInstance->Modules.AddService(*prov); - GetConfig(); + ConfigureProviders(); } void OnServiceDel(ServiceProvider& prov) CXX11_OVERRIDE diff --git a/src/modules/m_restrictchans.cpp b/src/modules/m_restrictchans.cpp index 9c7ed1213..348beed2c 100644 --- a/src/modules/m_restrictchans.cpp +++ b/src/modules/m_restrictchans.cpp @@ -22,21 +22,26 @@ #include "inspircd.h" +typedef insp::flat_set<std::string, irc::insensitive_swo> AllowChans; + class ModuleRestrictChans : public Module { - insp::flat_set<std::string, irc::insensitive_swo> allowchans; + AllowChans allowchans; public: void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE { - allowchans.clear(); + AllowChans newallows; ConfigTagList tags = ServerInstance->Config->ConfTags("allowchannel"); for(ConfigIter i = tags.first; i != tags.second; ++i) { - ConfigTag* tag = i->second; - std::string txt = tag->getString("name"); - allowchans.insert(txt); + const std::string name = i->second->getString("name"); + if (name.empty()) + throw ModuleException("Empty <allowchannel:name> at " + i->second->getTagLocation()); + + newallows.insert(name); } + allowchans.swap(newallows); } ModResult OnUserPreJoin(LocalUser* user, Channel* chan, const std::string& cname, std::string& privs, const std::string& keygiven) CXX11_OVERRIDE diff --git a/src/modules/m_securelist.cpp b/src/modules/m_securelist.cpp index aa14707b1..6d9b64df2 100644 --- a/src/modules/m_securelist.cpp +++ b/src/modules/m_securelist.cpp @@ -22,9 +22,11 @@ #include "inspircd.h" #include "modules/account.h" +typedef std::vector<std::string> AllowList; + class ModuleSecureList : public Module { - std::vector<std::string> allowlist; + AllowList allowlist; bool exemptregistered; unsigned int WaitTime; @@ -36,15 +38,22 @@ class ModuleSecureList : public Module void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE { - allowlist.clear(); + AllowList newallows; ConfigTagList tags = ServerInstance->Config->ConfTags("securehost"); for (ConfigIter i = tags.first; i != tags.second; ++i) - allowlist.push_back(i->second->getString("exception")); + { + std::string host = i->second->getString("exception"); + if (host.empty()) + throw ModuleException("<securehost:exception> is a required field at " + i->second->getTagLocation()); + newallows.push_back(host); + } ConfigTag* tag = ServerInstance->Config->ConfValue("securelist"); + exemptregistered = tag->getBool("exemptregistered"); WaitTime = tag->getDuration("waittime", 60, 1); + allowlist.swap(newallows); } diff --git a/src/modules/m_vhost.cpp b/src/modules/m_vhost.cpp index 01df33cae..478a5100a 100644 --- a/src/modules/m_vhost.cpp +++ b/src/modules/m_vhost.cpp @@ -22,35 +22,55 @@ #include "inspircd.h" +struct CustomVhost +{ + const std::string name; + const std::string password; + const std::string hash; + const std::string vhost; + + CustomVhost(const std::string& n, const std::string& p, const std::string& h, const std::string& v) + : name(n) + , password(p) + , hash(h) + , vhost(v) + { + } + + bool CheckPass(User* user, const std::string& pass) const + { + return ServerInstance->PassCompare(user, password, pass, hash); + } +}; + +typedef std::multimap<std::string, CustomVhost> CustomVhostMap; +typedef std::pair<CustomVhostMap::iterator, CustomVhostMap::iterator> MatchingConfigs; + /** Handle /VHOST */ class CommandVhost : public Command { public: - CommandVhost(Module* Creator) : Command(Creator,"VHOST", 2) + CustomVhostMap vhosts; + + CommandVhost(Module* Creator) + : Command(Creator, "VHOST", 2) { syntax = "<username> <password>"; } CmdResult Handle(User* user, const Params& parameters) CXX11_OVERRIDE { - ConfigTagList tags = ServerInstance->Config->ConfTags("vhost"); - for(ConfigIter i = tags.first; i != tags.second; ++i) - { - ConfigTag* tag = i->second; - std::string mask = tag->getString("host"); - std::string username = tag->getString("user"); - std::string pass = tag->getString("pass"); - std::string hash = tag->getString("hash"); + MatchingConfigs matching = vhosts.equal_range(parameters[0]); - if (parameters[0] == username && ServerInstance->PassCompare(user, pass, parameters[1], hash)) + for (MatchingConfigs::first_type i = matching.first; i != matching.second; ++i) + { + CustomVhost config = i->second; + if (config.CheckPass(user, parameters[1])) { - if (!mask.empty()) - { - user->WriteNotice("Setting your VHost: " + mask); - user->ChangeDisplayedHost(mask); - return CMD_SUCCESS; - } + user->WriteNotice("Setting your VHost: " + config.vhost); + user->ChangeDisplayedHost(config.vhost); + return CMD_SUCCESS; } } @@ -64,13 +84,39 @@ class ModuleVHost : public Module CommandVhost cmd; public: - ModuleVHost() : cmd(this) + ModuleVHost() + : cmd(this) + { + } + + void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE { + CustomVhostMap newhosts; + ConfigTagList tags = ServerInstance->Config->ConfTags("vhost"); + for (ConfigIter i = tags.first; i != tags.second; ++i) + { + ConfigTag* tag = i->second; + std::string mask = tag->getString("host"); + if (mask.empty()) + throw ModuleException("<vhost:host> is empty! at " + tag->getTagLocation()); + std::string username = tag->getString("user"); + if (username.empty()) + throw ModuleException("<vhost:user> is empty! at " + tag->getTagLocation()); + std::string pass = tag->getString("pass"); + if (pass.empty()) + throw ModuleException("<vhost:pass> is empty! at " + tag->getTagLocation()); + std::string hash = tag->getString("hash"); + + CustomVhost vhost(username, pass, hash, mask); + newhosts.insert(std::make_pair(username, vhost)); + } + + cmd.vhosts.swap(newhosts); } Version GetVersion() CXX11_OVERRIDE { - return Version("Provides masking of user hostnames via traditional /VHOST command",VF_VENDOR); + return Version("Provides masking of user hostnames via traditional /VHOST command", VF_VENDOR); } }; |