diff options
author | Matthias Schiffer <matthias@gamezock.de> | 2009-08-29 16:19:50 +0200 |
---|---|---|
committer | Matthias Schiffer <matthias@gamezock.de> | 2009-08-29 16:19:50 +0200 |
commit | 8798ddc04b5cfe78180ca119f12486df0afb1bd0 (patch) | |
tree | 4663ce78dd58c04c23d556610bf9ea91f3927ec6 | |
parent | bf56fa726e1d6ed228fde841e6312d61122174da (diff) | |
download | mad-8798ddc04b5cfe78180ca119f12486df0afb1bd0.tar mad-8798ddc04b5cfe78180ca119f12486df0afb1bd0.zip |
AuthProviderFile: Auslesen von gehashten Passwörtern
-rw-r--r-- | src/Common/Hash.h | 7 | ||||
-rw-r--r-- | src/mad-server.conf | 1 | ||||
-rw-r--r-- | src/modules/AuthProviderFile/AuthProviderFile.cpp | 87 | ||||
-rw-r--r-- | src/modules/AuthProviderFile/AuthProviderFile.h | 23 | ||||
-rw-r--r-- | 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 <string> #include <vector> +#include <boost/algorithm/string/case_conv.hpp> #include <boost/cstdint.hpp> namespace Mad { @@ -43,7 +44,7 @@ class MAD_COMMON_EXPORT Hash { std::vector<std::string> 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<boost::uint8_t> hash(const std::vector<boost::uint8_t> &in, unsigned int method) throw (Core::Exception); static std::vector<boost::uint8_t> hash(const std::vector<boost::uint8_t> &in, const std::string &method) throw (Core::Exception) { - std::map<std::string, unsigned int>::const_iterator methodIt = hashes.getMap().find(method); + std::map<std::string, unsigned int>::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 <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); } @@ -1 +1 @@ -root:admin +root:d033e22ae348aeb5660fc2140aec35850c4da997 |