summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Client/Authenticators/PasswordAuthenticator.cpp48
-rw-r--r--src/Client/Authenticators/PasswordAuthenticator.h6
-rw-r--r--src/Common/AuthBackend.h5
-rw-r--r--src/Common/AuthManager.cpp12
-rw-r--r--src/Common/AuthManager.h14
-rw-r--r--src/Common/CMakeLists.txt1
-rw-r--r--src/Common/Hash.h4
-rw-r--r--src/Core/Exception.cpp15
-rw-r--r--src/Server/ConnectionManager.cpp8
-rw-r--r--src/Server/ConnectionManager.h6
-rw-r--r--src/Server/RequestHandlers/ConnectionRequestHandlerGroup.cpp14
-rw-r--r--src/modules/AuthBackendFile/AuthBackendFile.cpp20
-rw-r--r--src/modules/AuthBackendFile/AuthBackendFile.h20
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);
}