From c964aa2708ed2839ded3c35eed7338f3e81f568f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 24 Aug 2009 04:47:54 +0200 Subject: =?UTF-8?q?Authentifikation:=20=C3=9Cbertrage=20Passw=C3=B6rter=20?= =?UTF-8?q?gehasht?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Authenticators/PasswordAuthenticator.cpp | 48 +++++++++++++++++++++- src/Client/Authenticators/PasswordAuthenticator.h | 6 ++- src/Common/AuthBackend.h | 5 ++- src/Common/AuthManager.cpp | 12 ++++-- src/Common/AuthManager.h | 14 +++++-- src/Common/CMakeLists.txt | 1 + src/Common/Hash.h | 4 ++ src/Core/Exception.cpp | 15 +++++++ src/Server/ConnectionManager.cpp | 8 ++-- src/Server/ConnectionManager.h | 6 +-- .../ConnectionRequestHandlerGroup.cpp | 14 ++++++- src/modules/AuthBackendFile/AuthBackendFile.cpp | 20 ++++++--- src/modules/AuthBackendFile/AuthBackendFile.h | 20 ++++++--- 13 files changed, 140 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/Client/Authenticators/PasswordAuthenticator.cpp b/src/Client/Authenticators/PasswordAuthenticator.cpp index 3aa9f41..6690b22 100644 --- a/src/Client/Authenticators/PasswordAuthenticator.cpp +++ b/src/Client/Authenticators/PasswordAuthenticator.cpp @@ -19,7 +19,9 @@ #include "PasswordAuthenticator.h" +#include #include +#include namespace Mad { namespace Client { @@ -29,9 +31,14 @@ void PasswordAuthenticator::PasswordAuthRequest::sendRequest() { Common::XmlPacket packet; packet.setType("Authenticate"); packet.set("method", "Password"); + packet.set("subMethod", hash); packet.set("user", username); - packet.set("data", std::vector(password.begin(), password.end())); + + if(hash == "Clear") + packet.set("data", password); + else + packet.set("data", Common::Hash::hash(std::vector(password.begin(), password.end()), hash)); sendPacket(packet); } @@ -51,7 +58,44 @@ void PasswordAuthenticator::PasswordAuthRequest::handlePacket(boost::shared_ptr< } void PasswordAuthenticator::authenticate(Common::Application *application, Common::Connection *con, const std::string &username, const std::string &password) throw (Core::Exception) { - boost::shared_ptr request(new PasswordAuthRequest(application, username, password)); + std::string hash; + + { + boost::shared_ptr request(new Common::Requests::AuthMethodRequest(application)); + + application->getRequestManager()->sendRequest(con, request); + request->wait(); + + std::pair, Core::Exception> result = request->getResult(); + + if(!result.first || result.second) + throw result.second; + + const Common::XmlPacket::List *methods = result.first->getList("methods"); + + for(Common::XmlPacket::List::const_iterator method = methods->begin(); method != methods->end(); ++method) { + if(method->get("name") != "Password") + continue; + + const Common::XmlPacket::List *subMethods = method->getList("subMethods"); + + for(Common::XmlPacket::List::const_iterator subMethod = subMethods->begin(); subMethod != subMethods->end(); ++subMethod) { + if(Common::Hash::isHashSupported(subMethod->get("name"))) { + hash = subMethod->get("name"); + break; + } + } + + break; + } + + if(hash.empty()) + throw Core::Exception(Core::Exception::NOT_AVAILABLE); + } + + application->logf(Core::LoggerBase::LOG_VERBOSE, "Authenticating with method 'Password' using hash '%s'...", hash.c_str()); + + boost::shared_ptr request(new PasswordAuthRequest(application, username, password, hash)); application->getRequestManager()->sendRequest(con, request); request->wait(); diff --git a/src/Client/Authenticators/PasswordAuthenticator.h b/src/Client/Authenticators/PasswordAuthenticator.h index 70c3cf1..8fdd87c 100644 --- a/src/Client/Authenticators/PasswordAuthenticator.h +++ b/src/Client/Authenticators/PasswordAuthenticator.h @@ -35,13 +35,15 @@ class MAD_CLIENT_EXPORT PasswordAuthenticator { std::string username; std::string password; + std::string hash; + protected: virtual void sendRequest(); virtual void handlePacket(boost::shared_ptr packet); public: - PasswordAuthRequest(Common::Application *application, const std::string &username0, const std::string &password0) - : Common::Request(application), username(username0), password(password0) {} + PasswordAuthRequest(Common::Application *application, const std::string &username0, const std::string &password0, const std::string &hash0) + : Common::Request(application), username(username0), password(password0), hash(hash0) {} }; PasswordAuthenticator(); diff --git a/src/Common/AuthBackend.h b/src/Common/AuthBackend.h index 53c7769..d916d1d 100644 --- a/src/Common/AuthBackend.h +++ b/src/Common/AuthBackend.h @@ -38,9 +38,10 @@ class AuthBackend { friend class AuthManager; virtual const std::vector& getMethods() const = 0; + virtual const std::vector& getSubMethods(const std::string &method) const throw(Core::Exception) = 0; - virtual boost::shared_ptr authenticate(const std::string& /*method*/, const std::string& /*user*/, - const std::vector& /*data*/, std::vector& /*response*/, + virtual boost::shared_ptr authenticate(const std::string& /*method*/, const std::string& /*subMethod*/, + const std::string& /*user*/, const std::vector& /*data*/, std::vector& /*response*/, boost::shared_ptr /*context*/) throw(Core::Exception) = 0; public: diff --git a/src/Common/AuthManager.cpp b/src/Common/AuthManager.cpp index ffb8453..82fbda5 100644 --- a/src/Common/AuthManager.cpp +++ b/src/Common/AuthManager.cpp @@ -45,13 +45,19 @@ std::vector AuthManager::getMethods() { return backend->getMethods(); } -boost::shared_ptr AuthManager::authenticate(const std::string &method, const std::string &user, const std::vector &data, - std::vector &response, boost::shared_ptr context) throw(Core::Exception) { +std::vector AuthManager::getSubMethods(const std::string &method) throw(Core::Exception) { + boost::shared_lock lock(mutex); + + return backend->getSubMethods(method); +} + +boost::shared_ptr AuthManager::authenticate(const std::string &method, const std::string &subMethod, const std::string &user, + const std::vector &data, std::vector &response, boost::shared_ptr context) throw(Core::Exception) { boost::lock_guard lock(mutex); response.clear(); - return backend->authenticate(method, user, data, response, context); + return backend->authenticate(method, subMethod, user, data, response, context); } } diff --git a/src/Common/AuthManager.h b/src/Common/AuthManager.h index 1516526..65e1fd3 100644 --- a/src/Common/AuthManager.h +++ b/src/Common/AuthManager.h @@ -53,8 +53,12 @@ class MAD_COMMON_EXPORT AuthManager : private boost::noncopyable { return methods; } - virtual boost::shared_ptr authenticate(const std::string& /*method*/, const std::string& /*user*/, - const std::vector& /*data*/, std::vector& /*response*/, + virtual const std::vector& getSubMethods(const std::string& /*method*/) const throw(Core::Exception) { + throw Core::Exception(Core::Exception::NOT_IMPLEMENTED); + } + + virtual boost::shared_ptr authenticate(const std::string& /*method*/, const std::string& /*subMethod*/, + const std::string& /*user*/, const std::vector& /*data*/, std::vector& /*response*/, boost::shared_ptr /*context*/) throw(Core::Exception) { throw Core::Exception(Core::Exception::NOT_IMPLEMENTED); } @@ -73,9 +77,11 @@ class MAD_COMMON_EXPORT AuthManager : private boost::noncopyable { void unregisterBackend(boost::shared_ptr oldBackend); std::vector getMethods(); + std::vector getSubMethods(const std::string &method) throw(Core::Exception); - boost::shared_ptr authenticate(const std::string &method, const std::string &user, const std::vector &data, - std::vector &response, boost::shared_ptr context = boost::shared_ptr()) throw(Core::Exception); + boost::shared_ptr authenticate(const std::string &method, const std::string &subMethod, + const std::string &user, const std::vector &data, std::vector &response, + boost::shared_ptr context = boost::shared_ptr()) throw(Core::Exception); }; } diff --git a/src/Common/CMakeLists.txt b/src/Common/CMakeLists.txt index 129c7de..e370c54 100644 --- a/src/Common/CMakeLists.txt +++ b/src/Common/CMakeLists.txt @@ -11,6 +11,7 @@ mad_library(Common RequestHandlers/SimpleRequestHandlerGroup.cpp RequestHandlers/SimpleRequestHandlerGroup.h RequestHandlers/StatusRequestHandler.cpp RequestHandlers/StatusRequestHandler.h + Requests/AuthMethodRequest.h Requests/DisconnectRequest.cpp Requests/DisconnectRequest.h Requests/FSInfoRequest.h Requests/IdentifyRequest.cpp Requests/IdentifyRequest.h diff --git a/src/Common/Hash.h b/src/Common/Hash.h index 69b3318..06562e2 100644 --- a/src/Common/Hash.h +++ b/src/Common/Hash.h @@ -66,6 +66,10 @@ class MAD_COMMON_EXPORT Hash { return hashes.getList(); } + static bool isHashSupported(const std::string &method) { + return (hashes.getMap().find(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) { diff --git a/src/Core/Exception.cpp b/src/Core/Exception.cpp index 3e9da4d..220e6fd 100644 --- a/src/Core/Exception.cpp +++ b/src/Core/Exception.cpp @@ -33,34 +33,49 @@ void Exception::updateWhatStr() { switch(errorCode) { case SUCCESS: whatStr += "Success"; + break; case UNEXPECTED_PACKET: whatStr += "An unexpected packet was received"; + break; case INVALID_ACTION: whatStr += "The action is invalid"; + break; case NOT_AVAILABLE: whatStr += "Not available"; + break; case NOT_FINISHED: whatStr += "Not finished"; + break; case NOT_IMPLEMENTED: whatStr += "Not implemented"; + break; case NOT_FOUND: whatStr += "Not found"; + break; case INVALID_INPUT: whatStr += "Invalid input"; + break; case PERMISSION: whatStr += "Permission denied"; + break; case INTERNAL_ERRNO: whatStr += std::strerror(subCode); + break; case INVALID_ADDRESS: whatStr += "Invalid address"; + break; case ALREADY_IDENTIFIED: whatStr += "The host is already identified"; + break; case UNKNOWN_DAEMON: whatStr += "The daemon is unknown"; + break; case DUPLICATE_ENTRY: whatStr += "Duplicate entry"; + break; case AUTHENTICATION: whatStr += "Authentication failure"; + break; default: whatStr += "Unknown error"; } diff --git a/src/Server/ConnectionManager.cpp b/src/Server/ConnectionManager.cpp index c49e7e8..b9490bc 100644 --- a/src/Server/ConnectionManager.cpp +++ b/src/Server/ConnectionManager.cpp @@ -58,11 +58,11 @@ bool ConnectionManager::ServerConnection::disconnect() { } boost::shared_ptr ConnectionManager::ServerConnection::authenticate(const std::string &method, - const std::string &user, const std::vector &data, std::vector &response) { + const std::string &subMethod, const std::string &user, const std::vector &data, std::vector &response) { if(!isIdentified()) type = CLIENT; - authContext = application->getAuthManager()->authenticate(method, user, data, response, authContext); + authContext = application->getAuthManager()->authenticate(method, subMethod, user, data, response, authContext); return authContext; } @@ -294,7 +294,7 @@ void ConnectionManager::identifyDaemonConnection(Common::Connection *con, const } boost::shared_ptr ConnectionManager::authenticateConnection(Common::Connection *con, const std::string &method, - const std::string &user, const std::vector &data, std::vector &response) { + const std::string &subMethod, const std::string &user, const std::vector &data, std::vector &response) { // TODO Logging ServerConnection *connection = dynamic_cast(con); @@ -305,7 +305,7 @@ boost::shared_ptr ConnectionManager::authenticateConn if(!connection->isIdentified()) connection->identify(); - return connection->authenticate(method, user, data, response); + return connection->authenticate(method, subMethod, user, data, response); } std::vector ConnectionManager::getDaemonList() const { diff --git a/src/Server/ConnectionManager.h b/src/Server/ConnectionManager.h index 067ce28..9638f38 100644 --- a/src/Server/ConnectionManager.h +++ b/src/Server/ConnectionManager.h @@ -101,8 +101,8 @@ class MAD_SERVER_EXPORT ConnectionManager : public Core::Configurable, private b return (authContext.get() != 0 && authContext->isAuthenticated()); } - boost::shared_ptr authenticate(const std::string &method, const std::string &user, - const std::vector &data, std::vector &response); + boost::shared_ptr authenticate(const std::string &method, const std::string &subMethod, + const std::string &user, const std::vector &data, std::vector &response); }; friend class Application; @@ -142,7 +142,7 @@ class MAD_SERVER_EXPORT ConnectionManager : public Core::Configurable, private b void identifyDaemonConnection(Common::Connection *con, const std::string &name) throw (Core::Exception); - boost::shared_ptr authenticateConnection(Common::Connection *con, const std::string &method, + boost::shared_ptr authenticateConnection(Common::Connection *con, const std::string &method, const std::string &subMethod, const std::string &user, const std::vector &data, std::vector &response); bool isAuthenticated(Common::Connection *con) const; diff --git a/src/Server/RequestHandlers/ConnectionRequestHandlerGroup.cpp b/src/Server/RequestHandlers/ConnectionRequestHandlerGroup.cpp index 37e2e79..7607171 100644 --- a/src/Server/RequestHandlers/ConnectionRequestHandlerGroup.cpp +++ b/src/Server/RequestHandlers/ConnectionRequestHandlerGroup.cpp @@ -43,6 +43,15 @@ void ConnectionRequestHandlerGroup::handleAuthMethodRequest(boost::shared_ptraddEntry(); entry->set("name", *method); + Common::XmlPacket::List *subList = entry->createList("subMethods"); + + const std::vector &subMethods = application->getAuthManager()->getSubMethods(*method); + + for(std::vector::const_iterator subMethod = subMethods.begin(); subMethod != subMethods.end(); ++subMethod) { + Common::XmlPacket::List::iterator subEntry = subList->addEntry(); + + subEntry->set("name", *subMethod); + } } } @@ -50,8 +59,9 @@ void ConnectionRequestHandlerGroup::handleAuthRequest(boost::shared_ptr response; boost::shared_ptr authContext = application->getConnectionManager()->authenticateConnection(connection, - packet->get("method"), packet->get("user"), - packet->get&>("data"), response); + packet->get("method"), packet->get("subMethod"), + packet->get("user"), packet->get&>("data"), + response); if(!response.empty()) ret->set("data", response); diff --git a/src/modules/AuthBackendFile/AuthBackendFile.cpp b/src/modules/AuthBackendFile/AuthBackendFile.cpp index ac7a1db..b05b2db 100644 --- a/src/modules/AuthBackendFile/AuthBackendFile.cpp +++ b/src/modules/AuthBackendFile/AuthBackendFile.cpp @@ -74,11 +74,11 @@ bool AuthBackendFile::handleConfigEntry(const Core::ConfigEntry &entry, bool /*h return true; } -boost::shared_ptr AuthBackendFile::authenticate(const std::string &method, const std::string &user, - const std::vector &data, std::vector& /*response*/, +boost::shared_ptr AuthBackendFile::authenticate(const std::string &method, const std::string &subMethod, + const std::string &user, const std::vector &data, std::vector& /*response*/, boost::shared_ptr context) throw(Core::Exception) { if(method != "Password") - throw(Core::Exception(Core::Exception::INVALID_INPUT)); + throw(Core::Exception(Core::Exception::NOT_IMPLEMENTED)); if(context.get() != 0 && dynamic_cast(context.get()) == 0) throw(Core::Exception(Core::Exception::INVALID_INPUT)); @@ -86,12 +86,20 @@ boost::shared_ptr AuthBackendFile::authenticate(const std:: if(context.get() == 0) context.reset(new AuthContextFile); - std::string password(data.begin(), data.end()); - std::map::iterator userIt = userMap.find(user); - if(userIt == userMap.end() || password != userIt->second) + if(userIt == userMap.end()) throw(Core::Exception(Core::Exception::AUTHENTICATION)); + if(subMethod == "Clear") { + if(userIt->second != std::string(data.begin(), data.end())) + throw(Core::Exception(Core::Exception::AUTHENTICATION)); + } + else { + if(!std::equal(data.begin(), data.end(), Common::Hash::hash(userIt->second, subMethod).begin())) + throw(Core::Exception(Core::Exception::AUTHENTICATION)); + } + + return context; } diff --git a/src/modules/AuthBackendFile/AuthBackendFile.h b/src/modules/AuthBackendFile/AuthBackendFile.h index 90f572c..5f13b51 100644 --- a/src/modules/AuthBackendFile/AuthBackendFile.h +++ b/src/modules/AuthBackendFile/AuthBackendFile.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -44,10 +45,11 @@ class MAD_MODULE_EXPORT AuthBackendFile : public Common::AuthBackend, private Co void readFile(const std::string &name); - std::vector methods; - Common::Application *application; + std::vector methods; + std::vector subMethods; + std::map userMap; protected: @@ -57,13 +59,21 @@ class MAD_MODULE_EXPORT AuthBackendFile : public Common::AuthBackend, private Co return methods; } - virtual boost::shared_ptr authenticate(const std::string &method, const std::string &user, - const std::vector &data, std::vector &response, + virtual const std::vector& getSubMethods(const std::string &method) const throw(Core::Exception) { + if(method != "Password") + throw(Core::Exception(Core::Exception::NOT_IMPLEMENTED)); + + return subMethods; + } + + virtual boost::shared_ptr authenticate(const std::string &method, const std::string &subMethod, + const std::string &user, const std::vector &data, std::vector &response, boost::shared_ptr context) throw(Core::Exception); public: - AuthBackendFile(Common::Application *application0) : application(application0) { + AuthBackendFile(Common::Application *application0) : application(application0), subMethods(Common::Hash::getHashList()) { methods.push_back("Password"); + subMethods.push_back("Clear"); application->getConfigManager()->registerConfigurable(this); } -- cgit v1.2.3