From 4fbd6681fedbff9b4cb04cc774f785cbe8b5c35b Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Tue, 18 Dec 2018 19:06:56 -0600 Subject: Make more modules rehash atomically (#1535) Have each module validate the values it loads before setting them, so any errors don't result in partial application of the configs --- src/modules/m_pbkdf2.cpp | 58 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 16 deletions(-) (limited to 'src/modules/m_pbkdf2.cpp') 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 ProviderConfigMap; + class ModulePBKDF2 : public Module { std::vector 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::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::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 -- cgit v1.3.1-10-gc9f91