diff options
Diffstat (limited to 'src/modules')
-rw-r--r-- | src/modules/AuthProviderFile/AuthProviderFile.cpp | 87 | ||||
-rw-r--r-- | src/modules/AuthProviderFile/AuthProviderFile.h | 23 |
2 files changed, 92 insertions, 18 deletions
diff --git a/src/modules/AuthProviderFile/AuthProviderFile.cpp b/src/modules/AuthProviderFile/AuthProviderFile.cpp index ce575cd..f670fec 100644 --- a/src/modules/AuthProviderFile/AuthProviderFile.cpp +++ b/src/modules/AuthProviderFile/AuthProviderFile.cpp @@ -18,8 +18,11 @@ */ #include "AuthProviderFile.h" + #include <Core/ConfigEntry.h> +#include <Common/Hash.h> +#include <cstdio> #include <fstream> #include <boost/regex.hpp> @@ -50,8 +53,31 @@ void AuthProviderFile::readFile(const std::string &name) { continue; } + std::string password = match[2].str(); + + if(filehash.empty()) { + userMap.insert(std::make_pair(match[1].str(), std::vector<boost::uint8_t>(password.begin(), password.end()))); + } + else { + std::vector<boost::uint8_t> data; + data.reserve(password.size()/2); + + for(size_t c = 0; c < password.size()-1; c += 2) { + char buffer[3] = {password[c], password[c+1], 0}; + unsigned char byte; - userMap.insert(std::make_pair(match[1].str(), match[2].str())); + if(std::sscanf(buffer, "%hhx", &byte) != 1) { + application->logf(Core::LoggerBase::LOG_WARNING, "AuthProviderFile: Malformed hash in file '%s'.", name.c_str()); + data.clear(); + break; + } + + data.push_back(byte); + } + + if(!data.empty()) + userMap.insert(std::make_pair(match[1].str(), data)); + } } } @@ -62,9 +88,17 @@ bool AuthProviderFile::handleConfigEntry(const Core::ConfigEntry &entry, bool /* if(entry[1].empty()) return true; - if(entry[1].getKey().matches("File")) { + if(entry[1].getKey().matches("Hash")) { if(entry[2].empty()) { - readFile(entry[1][0]); + filehash = entry[1][0]; + + if(!Common::Hash::isHashSupported(filehash)) + application->logf(Core::LoggerBase::LOG_WARNING, "AuthProviderFile: Unsupported hash '%s'", filehash.c_str()); + } + } + else if(entry[1].getKey().matches("File")) { + if(entry[2].empty()) { + files.push_back(entry[1][0]); } } else if(!entry[2].empty()) @@ -73,6 +107,53 @@ bool AuthProviderFile::handleConfigEntry(const Core::ConfigEntry &entry, bool /* return true; } +void AuthProviderFile::configFinished() { + if(filehash.empty() || boost::algorithm::to_lower_copy(filehash) == "clear") { + hashes = Common::Hash::getHashList(); + filehash.clear(); + } + else { + hashes.clear(); + hashes.push_back(filehash); + } + + hashes.push_back("Clear"); + + for(std::vector<std::string>::iterator file = files.begin(); file != files.end(); ++file) + readFile(*file); +} + +bool AuthProviderFile::checkPassword(const std::string &user, const std::vector<boost::uint8_t> &data, const std::string &hash) throw(Core::Exception) { + if((hash.empty() || boost::algorithm::to_lower_copy(hash) == "clear") && !filehash.empty()) { + std::vector<boost::uint8_t> password = getPassword(user, filehash); + std::vector<boost::uint8_t> hashdata = Common::Hash::hash(data, filehash); + + return (!password.empty() && hashdata.size() == password.size() && std::equal(hashdata.begin(), hashdata.end(), password.begin())); + } + else { + std::vector<boost::uint8_t> password = getPassword(user, hash); + return (!password.empty() && data.size() == password.size() && std::equal(data.begin(), data.end(), password.begin())); + } +} + +std::vector<boost::uint8_t> AuthProviderFile::getPassword(const std::string &user, const std::string &hash) throw(Core::Exception) { + std::map<std::string, std::vector<boost::uint8_t> >::iterator userIt = userMap.find(user); + if(userIt == userMap.end()) + return std::vector<boost::uint8_t>(); + + if(filehash.empty()) { + if(boost::algorithm::to_lower_copy(hash) == "clear") + return userIt->second; + else + return Common::Hash::hash(userIt->second, hash); + } + else if(boost::algorithm::to_lower_copy(filehash) == boost::algorithm::to_lower_copy(hash)) { + return userIt->second; + } + else + throw Core::Exception(Core::Exception::NOT_AVAILABLE); +} + } } } diff --git a/src/modules/AuthProviderFile/AuthProviderFile.h b/src/modules/AuthProviderFile/AuthProviderFile.h index da0c8cd..99deaa0 100644 --- a/src/modules/AuthProviderFile/AuthProviderFile.h +++ b/src/modules/AuthProviderFile/AuthProviderFile.h @@ -24,7 +24,6 @@ #include <Common/AuthProvider.h> #include <Common/Application.h> -#include <Common/Hash.h> #include <Core/Configurable.h> #include <Core/ConfigManager.h> @@ -39,32 +38,26 @@ class MAD_MODULE_EXPORT AuthProviderFile : public Common::AuthProvider, private Common::Application *application; - std::map<std::string, std::string> userMap; + std::map<std::string, std::vector<boost::uint8_t> > userMap; + + std::vector<std::string> files; + std::string filehash; std::vector<std::string> hashes; protected: virtual bool handleConfigEntry(const Core::ConfigEntry &entry, bool /*handled*/); + virtual void configFinished(); virtual const std::vector<std::string>& getHashes() const { return hashes; } - virtual std::vector<boost::uint8_t> getPassword(const std::string &user, const std::string &hash) throw(Core::Exception) { - std::map<std::string, std::string>::iterator userIt = userMap.find(user); - if(userIt == userMap.end()) - return std::vector<boost::uint8_t>(); - - if(hash == "Clear") - return std::vector<boost::uint8_t>(userIt->second.begin(), userIt->second.end()); - else - return Common::Hash::hash(std::vector<boost::uint8_t>(userIt->second.begin(), userIt->second.end()), hash); - } + virtual bool checkPassword(const std::string &user, const std::vector<boost::uint8_t> &data, const std::string &hash) throw(Core::Exception); + virtual std::vector<boost::uint8_t> getPassword(const std::string &user, const std::string &hash) throw(Core::Exception); public: - AuthProviderFile(Common::Application *application0) : application(application0), hashes(Common::Hash::getHashList()) { - hashes.push_back("Clear"); - + AuthProviderFile(Common::Application *application0) : application(application0) { application->getConfigManager()->registerConfigurable(this); } |