From 96b69222fa0c22d0eaefaae291e78913b2ae13e9 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 27 Aug 2009 18:39:44 +0200 Subject: =?UTF-8?q?AuthBackendChallengeResponse=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mad-server.conf | 1 + src/madc.cpp | 11 ++- .../AuthBackendChallengeResponse.cpp | 76 ++++++++++++++++++ .../AuthBackendChallengeResponse.h | 90 ++++++++++++++++++++++ .../AuthBackendChallengeResponse/CMakeLists.txt | 8 ++ .../AuthBackendChallengeResponse/Module.cpp | 30 ++++++++ src/modules/AuthBackendChallengeResponse/Module.h | 52 +++++++++++++ .../AuthBackendPassword/AuthBackendPassword.cpp | 4 +- src/modules/CMakeLists.txt | 1 + 9 files changed, 270 insertions(+), 3 deletions(-) create mode 100644 src/modules/AuthBackendChallengeResponse/AuthBackendChallengeResponse.cpp create mode 100644 src/modules/AuthBackendChallengeResponse/AuthBackendChallengeResponse.h create mode 100644 src/modules/AuthBackendChallengeResponse/CMakeLists.txt create mode 100644 src/modules/AuthBackendChallengeResponse/Module.cpp create mode 100644 src/modules/AuthBackendChallengeResponse/Module.h diff --git a/src/mad-server.conf b/src/mad-server.conf index ff8249c..1ea3f70 100644 --- a/src/mad-server.conf +++ b/src/mad-server.conf @@ -1,5 +1,6 @@ LoadModule "FileLogger" +LoadModule "AuthBackendChallengeResponse" LoadModule "AuthBackendPassword" LoadModule "AuthProviderFile" diff --git a/src/madc.cpp b/src/madc.cpp index 5f6039d..0f4639d 100644 --- a/src/madc.cpp +++ b/src/madc.cpp @@ -31,6 +31,7 @@ #include "Client/CommandParser.h" #include "Client/InformationManager.h" #include "Client/PasswordReader.h" +#include "Client/Authenticators/ChallengeResponseAuthenticator.h" #include "Client/Authenticators/PasswordAuthenticator.h" #include @@ -80,7 +81,15 @@ int main(int argc, char *argv[]) { std::getline(std::cin, username); password = Client::PasswordReader::readPassword("Password: "); - Client::Authenticators::PasswordAuthenticator::authenticate(&application, connection, username, password); + try { + Client::Authenticators::ChallengeResponseAuthenticator::authenticate(&application, connection, username, password); + } + catch(Core::Exception e) { + if(e.getErrorCode() != Core::Exception::NOT_AVAILABLE) + throw e; + + Client::Authenticators::PasswordAuthenticator::authenticate(&application, connection, username, password); + } } std::cerr << "Login successful." << std::endl << std::endl; diff --git a/src/modules/AuthBackendChallengeResponse/AuthBackendChallengeResponse.cpp b/src/modules/AuthBackendChallengeResponse/AuthBackendChallengeResponse.cpp new file mode 100644 index 0000000..39f2672 --- /dev/null +++ b/src/modules/AuthBackendChallengeResponse/AuthBackendChallengeResponse.cpp @@ -0,0 +1,76 @@ +/* + * AuthBackendChallengeResponse.cpp + * + * Copyright (C) 2009 Matthias Schiffer + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along + * with this program. If not, see . + */ + +#include "AuthBackendChallengeResponse.h" + +#include + +namespace Mad { +namespace Modules { +namespace AuthBackendChallengeResponse { + +const std::string AuthBackendChallengeResponse::methodName = "Challenge-Response"; + +AuthBackendChallengeResponse::AuthContextChallengeResponse::AuthContextChallengeResponse(AuthBackendChallengeResponse *backend) : authenticated(false) { + challenge.reserve(20); + + for(int i = 0; i < 20; ++i) + challenge.push_back(backend->randomGenerator()); +} + +boost::shared_ptr AuthBackendChallengeResponse::authenticate(boost::shared_ptr provider, const std::string &subMethod, + const std::string &user, const std::vector &data, std::vector &response, + boost::shared_ptr context) throw(Core::Exception) { + if(context && dynamic_cast(context.get()) == 0) + throw(Core::Exception(Core::Exception::INVALID_INPUT)); + + std::vector allowedMethods = getSubMethods(provider); + if(std::find(allowedMethods.begin(), allowedMethods.end(), subMethod) == allowedMethods.end()) + throw(Core::Exception(Core::Exception::INVALID_INPUT)); + + if(!context) { + boost::shared_ptr contextCR(new AuthContextChallengeResponse(this)); + context = contextCR; + + response.insert(response.end(), contextCR->challenge.begin(), contextCR->challenge.end()); + } + else { + boost::shared_ptr contextCR = boost::dynamic_pointer_cast(context); + + std::vector password = provider->getPassword(user, subMethod); + if(password.empty()) + throw Core::Exception(Core::Exception::AUTHENTICATION); + + password.insert(password.end(), contextCR->challenge.begin(), contextCR->challenge.end()); + + password = Common::Hash::hash(password, subMethod); + + if(password.size() != data.size() || !std::equal(password.begin(), password.end(), data.begin())) + throw Core::Exception(Core::Exception::AUTHENTICATION); + + contextCR->authenticated = true; + } + + + return context; +} + +} +} +} diff --git a/src/modules/AuthBackendChallengeResponse/AuthBackendChallengeResponse.h b/src/modules/AuthBackendChallengeResponse/AuthBackendChallengeResponse.h new file mode 100644 index 0000000..782f441 --- /dev/null +++ b/src/modules/AuthBackendChallengeResponse/AuthBackendChallengeResponse.h @@ -0,0 +1,90 @@ +/* + * AuthBackendChallengeResponse.h + * + * Copyright (C) 2008 Matthias Schiffer + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along + * with this program. If not, see . + */ + +#ifndef MAD_MODULES_AUTHBACKENDCHALLENGERESPONSE_AUTHBACKENDCHALLENGERESPONSE_H_ +#define MAD_MODULES_AUTHBACKENDCHALLENGERESPONSE_AUTHBACKENDCHALLENGERESPONSE_H_ + +#include "../export.h" + +#include +#include +#include +#include + +#include +#include +#include + + +namespace Mad { +namespace Modules { +namespace AuthBackendChallengeResponse { + +class MAD_MODULE_EXPORT AuthBackendChallengeResponse : public Common::AuthBackend, private boost::noncopyable { + private: + class AuthContextChallengeResponse : public Common::AuthContext { + private: + friend class AuthBackendChallengeResponse; + + bool authenticated; + std::vector challenge; + + AuthContextChallengeResponse(AuthBackendChallengeResponse *backend); + + protected: + virtual bool isAuthenticated() const { + return authenticated; + } + }; + + static const std::string methodName; + + Common::Application *application; + + boost::mt19937 rng; + boost::uniform_int byteDistribution; + boost::variate_generator > randomGenerator; + + + protected: + virtual const std::string& getMethodName() const { + return methodName; + } + + virtual std::vector getSubMethods(boost::shared_ptr provider) const { + std::vector ret; + ret.push_back(provider->getHashes().front()); + + return ret; + } + + virtual boost::shared_ptr authenticate(boost::shared_ptr provider, const std::string &subMethod, + const std::string &user, const std::vector &data, std::vector &response, + boost::shared_ptr context) throw(Core::Exception); + + public: + AuthBackendChallengeResponse(Common::Application *application0) + : application(application0), byteDistribution(0, 255), randomGenerator(rng, byteDistribution) {} +}; + +} +} +} + +#endif /* MAD_MODULES_AUTHBACKENDCHALLENGERESPONSE_AUTHBACKENDCHALLENGERESPONSE_H_ */ diff --git a/src/modules/AuthBackendChallengeResponse/CMakeLists.txt b/src/modules/AuthBackendChallengeResponse/CMakeLists.txt new file mode 100644 index 0000000..9dfd7ba --- /dev/null +++ b/src/modules/AuthBackendChallengeResponse/CMakeLists.txt @@ -0,0 +1,8 @@ +include_directories(${INCLUDES}) + +mad_module(AuthBackendChallengeResponse + Module.cpp Module.h + AuthBackendChallengeResponse.cpp AuthBackendChallengeResponse.h +) + +mad_module_libraries(AuthBackendChallengeResponse) diff --git a/src/modules/AuthBackendChallengeResponse/Module.cpp b/src/modules/AuthBackendChallengeResponse/Module.cpp new file mode 100644 index 0000000..f2fa0c2 --- /dev/null +++ b/src/modules/AuthBackendChallengeResponse/Module.cpp @@ -0,0 +1,30 @@ +/* + * Module.cpp + * + * Copyright (C) 2009 Matthias Schiffer + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along + * with this program. If not, see . + */ + +#include "../export.h" + +#include "Module.h" + +extern "C" { + +MAD_MODULE_EXPORT Mad::Common::Module* AuthBackendChallengeResponse_create(Mad::Common::Application *application) { + return new Mad::Modules::AuthBackendChallengeResponse::Module(application); +} + +} diff --git a/src/modules/AuthBackendChallengeResponse/Module.h b/src/modules/AuthBackendChallengeResponse/Module.h new file mode 100644 index 0000000..7a5891b --- /dev/null +++ b/src/modules/AuthBackendChallengeResponse/Module.h @@ -0,0 +1,52 @@ +/* + * Module.h + * + * Copyright (C) 2009 Matthias Schiffer + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along + * with this program. If not, see . + */ + +#ifndef MAD_MODULES_AUTHBACKENDCHALLENGERESPONSE_MODULE_H_ +#define MAD_MODULES_AUTHBACKENDCHALLENGERESPONSE_MODULE_H_ + +#include "AuthBackendChallengeResponse.h" + +#include +#include + +namespace Mad { +namespace Modules { +namespace AuthBackendChallengeResponse { + +class Module : public Common::Module { + private: + Common::Application *application; + + boost::shared_ptr backend; + + public: + Module(Common::Application *application0) : application(application0), backend(new AuthBackendChallengeResponse(application)) { + application->getAuthManager()->registerBackend(backend); + } + + virtual ~Module() { + application->getAuthManager()->unregisterBackend(backend); + } +}; + +} +} +} + +#endif /* MAD_MODULES_AUTHBACKENDCHALLENGERESPONSE_MODULE_H_ */ diff --git a/src/modules/AuthBackendPassword/AuthBackendPassword.cpp b/src/modules/AuthBackendPassword/AuthBackendPassword.cpp index 7e5aca9..1b38002 100644 --- a/src/modules/AuthBackendPassword/AuthBackendPassword.cpp +++ b/src/modules/AuthBackendPassword/AuthBackendPassword.cpp @@ -28,14 +28,14 @@ const std::string AuthBackendPassword::methodName = "Password"; boost::shared_ptr AuthBackendPassword::authenticate(boost::shared_ptr provider, const std::string &subMethod, const std::string &user, const std::vector &data, std::vector& /*response*/, boost::shared_ptr context) throw(Core::Exception) { - if(context.get() != 0 && dynamic_cast(context.get()) == 0) + if(context && dynamic_cast(context.get()) == 0) throw(Core::Exception(Core::Exception::INVALID_INPUT)); std::vector allowedMethods = getSubMethods(provider); if(std::find(allowedMethods.begin(), allowedMethods.end(), subMethod) == allowedMethods.end()) throw(Core::Exception(Core::Exception::INVALID_INPUT)); - if(context.get() == 0) + if(!context) context.reset(new AuthContextPassword); if(!provider->checkPassword(user, data, subMethod)) diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt index 0e198f8..e87d6af 100644 --- a/src/modules/CMakeLists.txt +++ b/src/modules/CMakeLists.txt @@ -33,6 +33,7 @@ macro(mad_module_libraries name) endif(WITH_${upper_name}) endmacro(mad_module_libraries) +add_subdirectory(AuthBackendChallengeResponse) add_subdirectory(AuthBackendPassword) add_subdirectory(AuthProviderFile) add_subdirectory(FileLogger) -- cgit v1.2.3