diff options
Diffstat (limited to 'src/Server')
-rw-r--r-- | src/Server/ConnectionManager.cpp | 50 | ||||
-rw-r--r-- | src/Server/ConnectionManager.h | 27 | ||||
-rw-r--r-- | src/Server/RequestHandlers/ConnectionRequestHandlerGroup.cpp | 45 | ||||
-rw-r--r-- | src/Server/RequestHandlers/ConnectionRequestHandlerGroup.h | 2 | ||||
-rw-r--r-- | src/Server/RequestHandlers/DaemonRequestHandlerGroup.cpp | 7 | ||||
-rw-r--r-- | src/Server/RequestHandlers/DaemonRequestHandlerGroup.h | 2 |
6 files changed, 101 insertions, 32 deletions
diff --git a/src/Server/ConnectionManager.cpp b/src/Server/ConnectionManager.cpp index 160f3c3..e52e8c4 100644 --- a/src/Server/ConnectionManager.cpp +++ b/src/Server/ConnectionManager.cpp @@ -22,6 +22,7 @@ #include "Application.h" #include <Core/ConfigEntry.h> #include <Core/ConfigManager.h> +#include <Common/AuthManager.h> #include <Common/RequestManager.h> #include <Common/RequestHandlers/FSInfoRequestHandler.h> #include <Common/RequestHandlers/StatusRequestHandler.h> @@ -32,7 +33,6 @@ #include <Net/Packet.h> #include <Net/Listener.h> -//#include <unistd.h> #include <algorithm> namespace Mad { @@ -42,8 +42,8 @@ bool ConnectionManager::ServerConnection::send(const Net::Packet &packet) { return connection->send(packet); } -ConnectionManager::ServerConnection::ServerConnection(Core::Application *application, boost::shared_ptr<Net::Connection> connection0) -: Common::Connection(application), connection(connection0), type(UNKNOWN), hostInfo(0) { +ConnectionManager::ServerConnection::ServerConnection(Common::Application *application0, boost::shared_ptr<Net::Connection> connection0) +: Common::Connection(application0), application(application0), connection(connection0), type(UNKNOWN), hostInfo(0) { connection->connectSignalReceive(boost::bind(&ServerConnection::receive, this, _1)); } @@ -57,6 +57,16 @@ bool ConnectionManager::ServerConnection::disconnect() { return true; } +boost::shared_ptr<const Common::AuthContext> ConnectionManager::ServerConnection::authenticate(const std::string &method, + const std::string &user, const std::vector<boost::uint8_t> &challenge, std::vector<boost::uint8_t> &response) { + if(!isIdentified()) + type = CLIENT; + + authContext = application->getAuthManager()->authenticate(method, user, challenge, response, authContext); + + return authContext; +} + /*void* ConnectionManager::ServerConnection::getCertificate(size_t *size) const { const gnutls_datum_t *cert = connection->getCertificate(); @@ -203,7 +213,6 @@ ConnectionManager::ConnectionManager(Application *application0) : application(ap connectionRequestHandlerGroup(new RequestHandlers::ConnectionRequestHandlerGroup(application)), daemonRequestHandlerGroup(new RequestHandlers::DaemonRequestHandlerGroup), userRequestHandlerGroup(new RequestHandlers::UserRequestHandlerGroup(application)) { - //requestManager->registerPacketType<RequestHandlers::GSSAPIAuthRequestHandler>("AuthGSSAPI"); application->getRequestManager()->registerPacketType<Common::RequestHandlers::FSInfoRequestHandler>("FSInfo"); application->getRequestManager()->registerPacketType<Common::RequestHandlers::StatusRequestHandler>("GetStatus"); @@ -223,12 +232,11 @@ ConnectionManager::~ConnectionManager() { application->getRequestManager()->unregisterRequestHandlerGroup(daemonRequestHandlerGroup); application->getRequestManager()->unregisterRequestHandlerGroup(connectionRequestHandlerGroup); - //requestManager->unregisterPacketType("AuthGSSAPI"); application->getRequestManager()->unregisterPacketType("FSInfo"); application->getRequestManager()->unregisterPacketType("GetStatus"); } -boost::shared_ptr<Common::Connection> ConnectionManager::getDaemonConnection(const std::string &name) const throw (Core::Exception&) { +boost::shared_ptr<Common::Connection> ConnectionManager::getDaemonConnection(const std::string &name) const throw (Core::Exception) { std::map<std::string, Common::HostInfo>::const_iterator hostIt = daemonInfo.find(name); @@ -248,7 +256,7 @@ boost::shared_ptr<Common::Connection> ConnectionManager::getDaemonConnection(con throw Core::Exception(Core::Exception::NOT_AVAILABLE); } -std::string ConnectionManager::getDaemonName(const Common::Connection *con) const throw (Core::Exception&) { +std::string ConnectionManager::getDaemonName(const Common::Connection *con) const throw (Core::Exception) { const ServerConnection *connection = dynamic_cast<const ServerConnection*>(con); if(connection && connection->getConnectionType() == ServerConnection::DAEMON) @@ -257,13 +265,13 @@ std::string ConnectionManager::getDaemonName(const Common::Connection *con) cons throw Core::Exception(Core::Exception::UNKNOWN_DAEMON); } -void ConnectionManager::identifyDaemonConnection(Common::Connection *con, const std::string &name) throw (Core::Exception&) { +void ConnectionManager::identifyDaemonConnection(Common::Connection *con, const std::string &name) throw (Core::Exception) { // TODO Logging ServerConnection *connection = dynamic_cast<ServerConnection*>(con); if(!connection) - throw Core::Exception(Core::Exception::INVALID_ACTION); + throw Core::Exception(Core::Exception::INVALID_INPUT); if(connection->isIdentified()) throw Core::Exception(Core::Exception::ALREADY_IDENTIFIED); @@ -283,20 +291,21 @@ void ConnectionManager::identifyDaemonConnection(Common::Connection *con, const connection->identify(hostInfo); updateState(hostInfo, Common::HostInfo::RUNNING); - - application->logf("Identified as '%s'.", name.c_str()); } -void ConnectionManager::identifyClientConnection(Common::Connection *con) throw (Core::Exception&) { +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> &challenge, std::vector<boost::uint8_t> &response) { + // TODO Logging + ServerConnection *connection = dynamic_cast<ServerConnection*>(con); if(!connection) - throw Core::Exception(Core::Exception::INVALID_ACTION); + throw Core::Exception(Core::Exception::INVALID_INPUT); - if(connection->isIdentified()) - throw Core::Exception(Core::Exception::ALREADY_IDENTIFIED); + if(!connection->isIdentified()) + connection->identify(); - connection->identify(); + return connection->authenticate(method, user, challenge, response); } std::vector<Common::HostInfo> ConnectionManager::getDaemonList() const { @@ -309,5 +318,14 @@ std::vector<Common::HostInfo> ConnectionManager::getDaemonList() const { return ret; } +bool ConnectionManager::isAuthenticated(Common::Connection *con) const { + ServerConnection *connection = dynamic_cast<ServerConnection*>(con); + + if(!connection) + throw Core::Exception(Core::Exception::INVALID_INPUT); + + return connection->isAuthenticated(); +} + } } diff --git a/src/Server/ConnectionManager.h b/src/Server/ConnectionManager.h index bdf1b4d..e045a6a 100644 --- a/src/Server/ConnectionManager.h +++ b/src/Server/ConnectionManager.h @@ -24,6 +24,7 @@ #include <Core/Configurable.h> #include <Core/Exception.h> +#include <Common/AuthContext.h> #include <Common/Connection.h> #include <Common/HostInfo.h> #include <Common/RequestHandlerGroup.h> @@ -49,22 +50,25 @@ class Application; class MAD_SERVER_EXPORT ConnectionManager : public Core::Configurable, private boost::noncopyable { private: - class ServerConnection : public Common::Connection { + class MAD_SERVER_EXPORT ServerConnection : public Common::Connection { public: enum ConnectionType { UNKNOWN = 0, DAEMON, CLIENT }; private: + Common::Application *application; + boost::shared_ptr<Net::Connection> connection; ConnectionType type; Common::HostInfo *hostInfo; + boost::shared_ptr<Common::AuthContext> authContext; protected: virtual bool send(const Net::Packet &packet); public: - ServerConnection(Core::Application *application, boost::shared_ptr<Net::Connection> connection0); + ServerConnection(Common::Application *application0, boost::shared_ptr<Net::Connection> connection0); bool isConnected() const; @@ -92,6 +96,13 @@ class MAD_SERVER_EXPORT ConnectionManager : public Core::Configurable, private b type = DAEMON; hostInfo = info; } + + bool isAuthenticated() const { + 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> &challenge, std::vector<boost::uint8_t> &response); }; friend class Application; @@ -126,11 +137,15 @@ class MAD_SERVER_EXPORT ConnectionManager : public Core::Configurable, private b virtual void configFinished(); public: - boost::shared_ptr<Common::Connection> getDaemonConnection(const std::string &name) const throw (Core::Exception&); - std::string getDaemonName(const Common::Connection *con) const throw (Core::Exception&); + boost::shared_ptr<Common::Connection> getDaemonConnection(const std::string &name) const throw (Core::Exception); + std::string getDaemonName(const Common::Connection *con) const throw (Core::Exception); + + 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, + const std::string &user, const std::vector<boost::uint8_t> &challenge, std::vector<boost::uint8_t> &response); - void identifyDaemonConnection(Common::Connection *con, const std::string &name) throw (Core::Exception&); - void identifyClientConnection(Common::Connection *con) throw (Core::Exception&); + bool isAuthenticated(Common::Connection *con) const; std::vector<Common::HostInfo> getDaemonList() const; }; diff --git a/src/Server/RequestHandlers/ConnectionRequestHandlerGroup.cpp b/src/Server/RequestHandlers/ConnectionRequestHandlerGroup.cpp index e94853f..b59cc3d 100644 --- a/src/Server/RequestHandlers/ConnectionRequestHandlerGroup.cpp +++ b/src/Server/RequestHandlers/ConnectionRequestHandlerGroup.cpp @@ -21,6 +21,8 @@ #include "../Application.h" #include "../ConnectionManager.h" +#include <Common/AuthManager.h> + #include <Core/LogManager.h> #include <boost/date_time/posix_time/posix_time.hpp> @@ -29,9 +31,41 @@ namespace Mad { namespace Server { namespace RequestHandlers { -void ConnectionRequestHandlerGroup::handleDaemonListRequest(boost::shared_ptr<const Common::XmlPacket> /*packet*/, Common::XmlPacket *ret, +void ConnectionRequestHandlerGroup::handleAuthMethodRequest(boost::shared_ptr<const Common::XmlPacket> /*packet*/, Common::XmlPacket *ret, Common::Connection* /*connection*/) { - // TODO Require authentication + ret->setType("OK"); + + Common::XmlPacket::List *list = ret->createList("methods"); + + const std::vector<std::string> &methods = application->getAuthManager()->getMethods(); + + for(std::vector<std::string>::const_iterator method = methods.begin(); method != methods.end(); ++method) { + Common::XmlPacket::List::iterator entry = list->addEntry(); + + entry->set("name", *method); + } +} + +void ConnectionRequestHandlerGroup::handleAuthRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret, Common::Connection *connection) { + 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>&>("challenge"), response); + + if(!response.empty()) + ret->set("response", response); + + if(authContext->isAuthenticated()) + ret->setType("OK"); + else + ret->setType("Continue"); +} + +void ConnectionRequestHandlerGroup::handleDaemonListRequest(boost::shared_ptr<const Common::XmlPacket> /*packet*/, Common::XmlPacket *ret, + Common::Connection *connection) { + if(!application->getConnectionManager()->isAuthenticated(connection)) + throw(Core::Exception(Core::Exception::PERMISSION)); ret->setType("OK"); Common::XmlPacket::List *list = ret->createList("hosts"); @@ -48,10 +82,7 @@ void ConnectionRequestHandlerGroup::handleDaemonListRequest(boost::shared_ptr<co } void ConnectionRequestHandlerGroup::handleIdentifyRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret, Common::Connection *connection) { - if(packet->get<const std::string&>("hostname").empty()) - application->getConnectionManager()->identifyClientConnection(connection); - else - application->getConnectionManager()->identifyDaemonConnection(connection, packet->get<const std::string&>("hostname")); + application->getConnectionManager()->identifyDaemonConnection(connection, packet->get<const std::string&>("hostname")); ret->setType("OK"); } @@ -85,6 +116,8 @@ void ConnectionRequestHandlerGroup::handleLogRequest(boost::shared_ptr<const Com } ConnectionRequestHandlerGroup::ConnectionRequestHandlerGroup(Application *application0) : application(application0) { + registerHandler("GetAuthMethods", boost::bind(&ConnectionRequestHandlerGroup::handleAuthMethodRequest, this, _1, _2, _3)); + registerHandler("Authenticate", boost::bind(&ConnectionRequestHandlerGroup::handleAuthRequest, this, _1, _2, _3)); registerHandler("ListHosts", boost::bind(&ConnectionRequestHandlerGroup::handleDaemonListRequest, this, _1, _2, _3)); registerHandler("Identify", boost::bind(&ConnectionRequestHandlerGroup::handleIdentifyRequest, this, _1, _2, _3)); registerHandler("Log", boost::bind(&ConnectionRequestHandlerGroup::handleLogRequest, this, _1, _2, _3)); diff --git a/src/Server/RequestHandlers/ConnectionRequestHandlerGroup.h b/src/Server/RequestHandlers/ConnectionRequestHandlerGroup.h index 7f6b17c..f3d2138 100644 --- a/src/Server/RequestHandlers/ConnectionRequestHandlerGroup.h +++ b/src/Server/RequestHandlers/ConnectionRequestHandlerGroup.h @@ -35,6 +35,8 @@ class MAD_SERVER_EXPORT ConnectionRequestHandlerGroup : public Common::RequestHa private: Application *application; + void handleAuthMethodRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret, Common::Connection *connection); + void handleAuthRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret, Common::Connection *connection); void handleDaemonListRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret, Common::Connection *connection); void handleIdentifyRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret, Common::Connection *connection); void handleLogRequest(boost::shared_ptr<const Common::XmlPacket> packet, Common::XmlPacket *ret, Common::Connection *connection); diff --git a/src/Server/RequestHandlers/DaemonRequestHandlerGroup.cpp b/src/Server/RequestHandlers/DaemonRequestHandlerGroup.cpp index 0345d7b..ee79ff2 100644 --- a/src/Server/RequestHandlers/DaemonRequestHandlerGroup.cpp +++ b/src/Server/RequestHandlers/DaemonRequestHandlerGroup.cpp @@ -44,10 +44,13 @@ void DaemonRequestHandlerGroup::DaemonRequestHandler::handlePacket(boost::shared return; } - // TODO Require authentication + ConnectionManager *connectionManager = dynamic_cast<Application&>(*getApplication()).getConnectionManager(); + + if(!connectionManager->isAuthenticated(getConnection())) + throw(Core::Exception(Core::Exception::PERMISSION)); try { - boost::shared_ptr<Common::Connection> daemonCon = dynamic_cast<Application&>(*getApplication()).getConnectionManager()->getDaemonConnection(packet->get<const std::string&>("daemon")); + boost::shared_ptr<Common::Connection> daemonCon = connectionManager->getDaemonConnection(packet->get<const std::string&>("daemon")); boost::shared_ptr<Common::Request> request; if(type == "DaemonCommand") diff --git a/src/Server/RequestHandlers/DaemonRequestHandlerGroup.h b/src/Server/RequestHandlers/DaemonRequestHandlerGroup.h index 086bf16..8312709 100644 --- a/src/Server/RequestHandlers/DaemonRequestHandlerGroup.h +++ b/src/Server/RequestHandlers/DaemonRequestHandlerGroup.h @@ -47,8 +47,6 @@ class MAD_SERVER_EXPORT DaemonRequestHandlerGroup : public Common::RequestHandle : Common::RequestHandler(application), type(type0) {} }; - ConnectionManager *connectionManager; - std::set<std::string> types; public: |