#include "Swiften/Server/ServerFromClientSession.h" #include #include "Swiften/Elements/ProtocolHeader.h" #include "Swiften/Server/UserRegistry.h" #include "Swiften/Network/Connection.h" #include "Swiften/StreamStack/XMPPLayer.h" #include "Swiften/Elements/StreamFeatures.h" #include "Swiften/Elements/ResourceBind.h" #include "Swiften/Elements/StartSession.h" #include "Swiften/Elements/IQ.h" #include "Swiften/Elements/AuthSuccess.h" #include "Swiften/Elements/AuthFailure.h" #include "Swiften/Elements/AuthRequest.h" #include "Swiften/SASL/PLAINMessage.h" namespace Swift { ServerFromClientSession::ServerFromClientSession( const String& id, boost::shared_ptr connection, PayloadParserFactoryCollection* payloadParserFactories, PayloadSerializerCollection* payloadSerializers, UserRegistry* userRegistry) : Session(connection, payloadParserFactories, payloadSerializers), id_(id), userRegistry_(userRegistry), authenticated_(false), initialized(false) { } void ServerFromClientSession::handleElement(boost::shared_ptr element) { if (isInitialized()) { onElementReceived(element); } else { if (AuthRequest* authRequest = dynamic_cast(element.get())) { if (authRequest->getMechanism() != "PLAIN") { getXMPPLayer()->writeElement(boost::shared_ptr(new AuthFailure)); finishSession(NoSupportedAuthMechanismsError); } else { PLAINMessage plainMessage(authRequest->getMessage()); if (userRegistry_->isValidUserPassword(JID(plainMessage.getAuthenticationID(), getLocalJID().getDomain()), plainMessage.getPassword())) { getXMPPLayer()->writeElement(boost::shared_ptr(new AuthSuccess())); user_ = plainMessage.getAuthenticationID(); authenticated_ = true; getXMPPLayer()->resetParser(); } else { getXMPPLayer()->writeElement(boost::shared_ptr(new AuthFailure)); finishSession(AuthenticationFailedError); } } } else if (IQ* iq = dynamic_cast(element.get())) { if (boost::shared_ptr resourceBind = iq->getPayload()) { setRemoteJID(JID(user_, getLocalJID().getDomain(), resourceBind->getResource())); boost::shared_ptr resultResourceBind(new ResourceBind()); resultResourceBind->setJID(getRemoteJID()); getXMPPLayer()->writeElement(IQ::createResult(JID(), iq->getID(), resultResourceBind)); } else if (iq->getPayload()) { getXMPPLayer()->writeElement(IQ::createResult(getRemoteJID(), iq->getID())); setInitialized(); } } } } void ServerFromClientSession::handleStreamStart(const ProtocolHeader& incomingHeader) { setLocalJID(JID("", incomingHeader.getTo())); ProtocolHeader header; header.setFrom(incomingHeader.getTo()); header.setID(id_); getXMPPLayer()->writeHeader(header); boost::shared_ptr features(new StreamFeatures()); if (!authenticated_) { features->addAuthenticationMechanism("PLAIN"); } else { features->setHasResourceBind(); features->setHasSession(); } getXMPPLayer()->writeElement(features); } void ServerFromClientSession::setInitialized() { initialized = true; onSessionStarted(); } }