From 8798ddc04b5cfe78180ca119f12486df0afb1bd0 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 29 Aug 2009 16:19:50 +0200 Subject: =?UTF-8?q?AuthProviderFile:=20Auslesen=20von=20gehashten=20Passw?= =?UTF-8?q?=C3=B6rtern?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Common/Hash.h | 7 +- src/mad-server.conf | 1 + src/modules/AuthProviderFile/AuthProviderFile.cpp | 87 ++++++++++++++++++++++- src/modules/AuthProviderFile/AuthProviderFile.h | 23 +++--- src/users | 2 +- 5 files changed, 98 insertions(+), 22 deletions(-) diff --git a/src/Common/Hash.h b/src/Common/Hash.h index 06562e2..db581b7 100644 --- a/src/Common/Hash.h +++ b/src/Common/Hash.h @@ -28,6 +28,7 @@ #include #include +#include #include namespace Mad { @@ -43,7 +44,7 @@ class MAD_COMMON_EXPORT Hash { std::vector list; void addHash(const std::string &name, unsigned id) { - map.insert(std::make_pair(name, id)); + map.insert(std::make_pair(boost::algorithm::to_lower_copy(name), id)); list.push_back(name); } @@ -67,13 +68,13 @@ class MAD_COMMON_EXPORT Hash { } static bool isHashSupported(const std::string &method) { - return (hashes.getMap().find(method) != hashes.getMap().end()); + return (hashes.getMap().find(boost::algorithm::to_lower_copy(method)) != hashes.getMap().end()); } static std::vector hash(const std::vector &in, unsigned int method) throw (Core::Exception); static std::vector hash(const std::vector &in, const std::string &method) throw (Core::Exception) { - std::map::const_iterator methodIt = hashes.getMap().find(method); + std::map::const_iterator methodIt = hashes.getMap().find(boost::algorithm::to_lower_copy(method)); if(methodIt == hashes.getMap().end()) throw(Core::Exception(Core::Exception::NOT_IMPLEMENTED)); diff --git a/src/mad-server.conf b/src/mad-server.conf index 1ea3f70..7b176d4 100644 --- a/src/mad-server.conf +++ b/src/mad-server.conf @@ -24,6 +24,7 @@ X509CertFile ../Cert/cert.pem X509KeyFile ../Cert/key.pem AuthProviderFile { + Hash "SHA1" File "users" } 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 +#include +#include #include #include @@ -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(password.begin(), password.end()))); + } + else { + std::vector 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::iterator file = files.begin(); file != files.end(); ++file) + readFile(*file); +} + +bool AuthProviderFile::checkPassword(const std::string &user, const std::vector &data, const std::string &hash) throw(Core::Exception) { + if((hash.empty() || boost::algorithm::to_lower_copy(hash) == "clear") && !filehash.empty()) { + std::vector password = getPassword(user, filehash); + std::vector hashdata = Common::Hash::hash(data, filehash); + + return (!password.empty() && hashdata.size() == password.size() && std::equal(hashdata.begin(), hashdata.end(), password.begin())); + } + else { + std::vector password = getPassword(user, hash); + return (!password.empty() && data.size() == password.size() && std::equal(data.begin(), data.end(), password.begin())); + } +} + +std::vector AuthProviderFile::getPassword(const std::string &user, const std::string &hash) throw(Core::Exception) { + std::map >::iterator userIt = userMap.find(user); + if(userIt == userMap.end()) + return std::vector(); + + 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 #include -#include #include #include @@ -39,32 +38,26 @@ class MAD_MODULE_EXPORT AuthProviderFile : public Common::AuthProvider, private Common::Application *application; - std::map userMap; + std::map > userMap; + + std::vector files; + std::string filehash; std::vector hashes; protected: virtual bool handleConfigEntry(const Core::ConfigEntry &entry, bool /*handled*/); + virtual void configFinished(); virtual const std::vector& getHashes() const { return hashes; } - virtual std::vector getPassword(const std::string &user, const std::string &hash) throw(Core::Exception) { - std::map::iterator userIt = userMap.find(user); - if(userIt == userMap.end()) - return std::vector(); - - if(hash == "Clear") - return std::vector(userIt->second.begin(), userIt->second.end()); - else - return Common::Hash::hash(std::vector(userIt->second.begin(), userIt->second.end()), hash); - } + virtual bool checkPassword(const std::string &user, const std::vector &data, const std::string &hash) throw(Core::Exception); + virtual std::vector 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); } diff --git a/src/users b/src/users index 93dc7d2..17c56b3 100644 --- a/src/users +++ b/src/users @@ -1 +1 @@ -root:admin +root:d033e22ae348aeb5660fc2140aec35850c4da997 -- cgit v1.2.3