/* * PasswordAuthenticator.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 "PasswordAuthenticator.h" #include #include #include namespace Mad { namespace Client { namespace Authenticators { void PasswordAuthenticator::PasswordAuthRequest::sendRequest() { Common::XmlPacket packet; packet.setType("Authenticate"); packet.set("method", "Password"); packet.set("subMethod", hash); packet.set("user", username); if(hash == "Clear") packet.set("data", std::vector(password.begin(), password.end())); else packet.set("data", Common::Hash::hash(std::vector(password.begin(), password.end()), hash)); sendPacket(packet); } void PasswordAuthenticator::PasswordAuthRequest::handlePacket(boost::shared_ptr packet) { if(packet->getType() == "Error") { signalFinished(Core::Exception(packet->get("Where"), static_cast(packet->get("ErrorCode")), packet->get("SubCode"), packet->get("SubSubCode"))); return; } else if(packet->getType() != "OK") { signalFinished(Core::Exception(Core::Exception::UNEXPECTED_PACKET)); return; // TODO Logging } signalFinished(packet); } void PasswordAuthenticator::authenticate(Common::Application *application, Common::Connection *con, const std::string &username, const std::string &password) throw (Core::Exception) { std::string hash; { boost::shared_ptr request(new Common::Requests::AuthMethodRequest(application)); application->getRequestManager()->sendRequest(con, request); request->wait(); std::pair, 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("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("name"))) { hash = subMethod->get("name"); break; } } break; } if(hash.empty()) throw Core::Exception(Core::Exception::NOT_AVAILABLE); } application->logf(Core::Logger::LOG_VERBOSE, "Authenticating with method 'Password' using hash '%s'...", hash.c_str()); boost::shared_ptr request(new PasswordAuthRequest(application, username, password, hash)); application->getRequestManager()->sendRequest(con, request); request->wait(); std::pair, Core::Exception> result = request->getResult(); if(!result.first || result.second) throw result.second; } } } }