diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Client/Authenticators/PasswordAuthenticator.cpp | 48 | ||||
-rw-r--r-- | src/Client/Authenticators/PasswordAuthenticator.h | 6 | ||||
-rw-r--r-- | src/Common/AuthBackend.h | 5 | ||||
-rw-r--r-- | src/Common/AuthManager.cpp | 12 | ||||
-rw-r--r-- | src/Common/AuthManager.h | 14 | ||||
-rw-r--r-- | src/Common/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/Common/Hash.h | 4 | ||||
-rw-r--r-- | src/Core/Exception.cpp | 15 | ||||
-rw-r--r-- | src/Server/ConnectionManager.cpp | 8 | ||||
-rw-r--r-- | src/Server/ConnectionManager.h | 6 | ||||
-rw-r--r-- | src/Server/RequestHandlers/ConnectionRequestHandlerGroup.cpp | 14 | ||||
-rw-r--r-- | src/modules/AuthBackendFile/AuthBackendFile.cpp | 20 | ||||
-rw-r--r-- | src/modules/AuthBackendFile/AuthBackendFile.h | 20 |
13 files changed, 140 insertions, 33 deletions
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 <Common/Hash.h> #include <Common/RequestManager.h> +#include <Common/Requests/AuthMethodRequest.h> 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<boost::uint8_t>(password.begin(), password.end())); + + if(hash == "Clear") + packet.set("data", password); + else + packet.set("data", Common::Hash::hash(std::vector<boost::uint8_t>(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<PasswordAuthRequest> request(new PasswordAuthRequest(application, username, password)); + std::string hash; + + { + boost::shared_ptr<Common::Requests::AuthMethodRequest> request(new Common::Requests::AuthMethodRequest(application)); + + application->getRequestManager()->sendRequest(con, request); + request->wait(); + + std::pair<boost::shared_ptr<const Common::XmlPacket>, 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<const std::string&>("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<const std::string&>("name"))) { + hash = subMethod->get<const std::string&>("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<PasswordAuthRequest> 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<const Common::XmlPacket> 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<std::string>& getMethods() const = 0; + virtual const std::vector<std::string>& getSubMethods(const std::string &method) const throw(Core::Exception) = 0; - virtual boost::shared_ptr<AuthContext> authenticate(const std::string& /*method*/, const std::string& /*user*/, - const std::vector<boost::uint8_t>& /*data*/, std::vector<boost::uint8_t>& /*response*/, + virtual boost::shared_ptr<AuthContext> authenticate(const std::string& /*method*/, const std::string& /*subMethod*/, + const std::string& /*user*/, const std::vector<boost::uint8_t>& /*data*/, std::vector<boost::uint8_t>& /*response*/, boost::shared_ptr<AuthContext> /*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<std::string> AuthManager::getMethods() { return backend->getMethods(); } -boost::shared_ptr<AuthContext> AuthManager::authenticate(const std::string &method, const std::string &user, const std::vector<boost::uint8_t> &data, - std::vector<boost::uint8_t> &response, boost::shared_ptr<AuthContext> context) throw(Core::Exception) { +std::vector<std::string> AuthManager::getSubMethods(const std::string &method) throw(Core::Exception) { + boost::shared_lock<boost::shared_mutex> lock(mutex); + + return backend->getSubMethods(method); +} + +boost::shared_ptr<AuthContext> AuthManager::authenticate(const std::string &method, const std::string &subMethod, const std::string &user, + const std::vector<boost::uint8_t> &data, std::vector<boost::uint8_t> &response, boost::shared_ptr<AuthContext> context) throw(Core::Exception) { boost::lock_guard<boost::shared_mutex> 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<AuthContext> authenticate(const std::string& /*method*/, const std::string& /*user*/, - const std::vector<boost::uint8_t>& /*data*/, std::vector<boost::uint8_t>& /*response*/, + virtual const std::vector<std::string>& getSubMethods(const std::string& /*method*/) const throw(Core::Exception) { + throw Core::Exception(Core::Exception::NOT_IMPLEMENTED); + } + + virtual boost::shared_ptr<AuthContext> authenticate(const std::string& /*method*/, const std::string& /*subMethod*/, + const std::string& /*user*/, const std::vector<boost::uint8_t>& /*data*/, std::vector<boost::uint8_t>& /*response*/, boost::shared_ptr<AuthContext> /*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<AuthBackend> oldBackend); std::vector<std::string> getMethods(); + std::vector<std::string> getSubMethods(const std::string &method) throw(Core::Exception); - boost::shared_ptr<AuthContext> authenticate(const std::string &method, const std::string &user, const std::vector<boost::uint8_t> &data, - std::vector<boost::uint8_t> &response, boost::shared_ptr<AuthContext> context = boost::shared_ptr<AuthContext>()) throw(Core::Exception); + boost::shared_ptr<AuthContext> authenticate(const std::string &method, const std::string &subMethod, + const std::string &user, const std::vector<boost::uint8_t> &data, std::vector<boost::uint8_t> &response, + boost::shared_ptr<AuthContext> context = boost::shared_ptr<AuthContext>()) 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<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) { 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<const Common::AuthContext> ConnectionManager::ServerConnection::authenticate(const std::string &method, - const std::string &user, const std::vector<boost::uint8_t> &data, std::vector<boost::uint8_t> &response) { + const std::string &subMethod, const std::string &user, const std::vector<boost::uint8_t> &data, std::vector<boost::uint8_t> &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<const Common::AuthContext> ConnectionManager::authenticateConnection(Common::Connection *con, const std::string &method, - const std::string &user, const std::vector<boost::uint8_t> &data, std::vector<boost::uint8_t> &response) { + const std::string &subMethod, const std::string &user, const std::vector<boost::uint8_t> &data, std::vector<boost::uint8_t> &response) { // TODO Logging ServerConnection *connection = dynamic_cast<ServerConnection*>(con); @@ -305,7 +305,7 @@ boost::shared_ptr<const Common::AuthContext> ConnectionManager::authenticateConn if(!connection->isIdentified()) connection->identify(); - return connection->authenticate(method, user, data, response); + return connection->authenticate(method, subMethod, user, data, response); } std::vector<Common::HostInfo> 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<const Common::AuthContext> authenticate(const std::string &method, const std::string &user, - const std::vector<boost::uint8_t> &data, std::vector<boost::uint8_t> &response); + boost::shared_ptr<const Common::AuthContext> authenticate(const std::string &method, const std::string &subMethod, + const std::string &user, const std::vector<boost::uint8_t> &data, std::vector<boost::uint8_t> &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<const Common::AuthContext> authenticateConnection(Common::Connection *con, const std::string &method, + boost::shared_ptr<const Common::AuthContext> authenticateConnection(Common::Connection *con, const std::string &method, const std::string &subMethod, const std::string &user, const std::vector<boost::uint8_t> &data, std::vector<boost::uint8_t> &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_ptr<co Common::XmlPacket::List::iterator entry = list->addEntry(); entry->set("name", *method); + Common::XmlPacket::List *subList = entry->createList("subMethods"); + + const std::vector<std::string> &subMethods = application->getAuthManager()->getSubMethods(*method); + + for(std::vector<std::string>::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<const Co std::vector<boost::uint8_t> response; boost::shared_ptr<const Common::AuthContext> authContext = application->getConnectionManager()->authenticateConnection(connection, - packet->get<const std::string&>("method"), packet->get<const std::string&>("user"), - packet->get<const std::vector<boost::uint8_t>&>("data"), response); + packet->get<const std::string&>("method"), packet->get<const std::string&>("subMethod"), + packet->get<const std::string&>("user"), packet->get<const std::vector<boost::uint8_t>&>("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<Common::AuthContext> AuthBackendFile::authenticate(const std::string &method, const std::string &user, - const std::vector<boost::uint8_t> &data, std::vector<boost::uint8_t>& /*response*/, +boost::shared_ptr<Common::AuthContext> AuthBackendFile::authenticate(const std::string &method, const std::string &subMethod, + const std::string &user, const std::vector<boost::uint8_t> &data, std::vector<boost::uint8_t>& /*response*/, boost::shared_ptr<Common::AuthContext> 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<AuthContextFile*>(context.get()) == 0) throw(Core::Exception(Core::Exception::INVALID_INPUT)); @@ -86,12 +86,20 @@ boost::shared_ptr<Common::AuthContext> AuthBackendFile::authenticate(const std:: if(context.get() == 0) context.reset(new AuthContextFile); - std::string password(data.begin(), data.end()); - std::map<std::string, std::string>::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 <Common/AuthBackend.h> #include <Common/AuthContext.h> #include <Common/Application.h> +#include <Common/Hash.h> #include <Core/Configurable.h> #include <Core/ConfigManager.h> @@ -44,10 +45,11 @@ class MAD_MODULE_EXPORT AuthBackendFile : public Common::AuthBackend, private Co void readFile(const std::string &name); - std::vector<std::string> methods; - Common::Application *application; + std::vector<std::string> methods; + std::vector<std::string> subMethods; + std::map<std::string, std::string> userMap; protected: @@ -57,13 +59,21 @@ class MAD_MODULE_EXPORT AuthBackendFile : public Common::AuthBackend, private Co return methods; } - virtual boost::shared_ptr<Common::AuthContext> authenticate(const std::string &method, const std::string &user, - const std::vector<boost::uint8_t> &data, std::vector<boost::uint8_t> &response, + virtual const std::vector<std::string>& 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<Common::AuthContext> authenticate(const std::string &method, const std::string &subMethod, + const std::string &user, const std::vector<boost::uint8_t> &data, std::vector<boost::uint8_t> &response, boost::shared_ptr<Common::AuthContext> 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); } |