/* * 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(32); for(int i = 0; i < 32; ++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; } } } }