std::string tok;
ss.GetToken(tok);
- this->iterations = ConvToInt(tok);
+ this->iterations = ConvToNum<unsigned int>(tok);
ss.GetToken(tok);
this->hash = Base64ToBin(tok);
}
};
+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->getInt("iterations", 12288, 1);
- unsigned int global_dkey_length = tag->getInt("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->getInt("iterations", global_iterations, 1);
- pi->dkey_length = tag->getInt("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:
stdalgo::delete_all(providers);
}
- void Prioritize() CXX11_OVERRIDE
+ void OnServiceAdd(ServiceProvider& provider) CXX11_OVERRIDE
{
- OnLoadModule(NULL);
- }
-
- void OnLoadModule(Module* mod) CXX11_OVERRIDE
- {
- bool newProv = false;
- // As the module doesn't tell us what ServiceProviders it has, let's iterate all (yay ...) the ServiceProviders
- // Good thing people don't run loading and unloading those all the time
- for (std::multimap<std::string, ServiceProvider*>::iterator i = ServerInstance->Modules->DataProviders.begin(); i != ServerInstance->Modules->DataProviders.end(); ++i)
- {
- ServiceProvider* provider = i->second;
-
- // Does the service belong to the new mod?
- // In the case this is our first run (mod == NULL, continue anyway)
- if (mod && provider->creator != mod)
- continue;
+ // Check if it's a hash provider
+ if (provider.name.compare(0, 5, "hash/"))
+ return;
- // Check if it's a hash provider
- if (provider->name.compare(0, 5, "hash/"))
- continue;
+ HashProvider* hp = static_cast<HashProvider*>(&provider);
+ if (hp->IsKDF())
+ return;
- HashProvider* hp = static_cast<HashProvider*>(provider);
+ PBKDF2Provider* prov = new PBKDF2Provider(this, hp);
+ providers.push_back(prov);
+ ServerInstance->Modules.AddService(*prov);
- if (hp->IsKDF())
- continue;
-
- bool has_prov = false;
- for (std::vector<PBKDF2Provider*>::const_iterator j = providers.begin(); j != providers.end(); ++j)
- {
- if ((*j)->provider == hp)
- {
- has_prov = true;
- break;
- }
- }
- if (has_prov)
- continue;
-
- newProv = true;
-
- PBKDF2Provider* prov = new PBKDF2Provider(this, hp);
- providers.push_back(prov);
- ServerInstance->Modules->AddService(*prov);
- }
-
- if (newProv)
- GetConfig();
+ ConfigureProviders();
}
- void OnUnloadModule(Module* mod) CXX11_OVERRIDE
+ void OnServiceDel(ServiceProvider& prov) CXX11_OVERRIDE
{
- for (std::vector<PBKDF2Provider*>::iterator i = providers.begin(); i != providers.end(); )
+ for (std::vector<PBKDF2Provider*>::iterator i = providers.begin(); i != providers.end(); ++i)
{
PBKDF2Provider* item = *i;
- if (item->provider->creator != mod)
- {
- ++i;
+ if (item->provider != &prov)
continue;
- }
ServerInstance->Modules->DelService(*item);
delete item;
- i = providers.erase(i);
+ providers.erase(i);
+ break;
}
}