/* * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Swift { ServerFromClientSession::ServerFromClientSession( const std::string& id, std::shared_ptr connection, PayloadParserFactoryCollection* payloadParserFactories, PayloadSerializerCollection* payloadSerializers, XMLParserFactory* xmlParserFactory, UserRegistry* userRegistry) : Session(connection, payloadParserFactories, payloadSerializers, xmlParserFactory), id_(id), userRegistry_(userRegistry), authenticated_(false), initialized(false), allowSASLEXTERNAL(false) { } void ServerFromClientSession::handleElement(std::shared_ptr element) { if (isInitialized()) { onElementReceived(element); } else { if (AuthRequest* authRequest = dynamic_cast(element.get())) { if (authRequest->getMechanism() == "PLAIN" || (allowSASLEXTERNAL && authRequest->getMechanism() == "EXTERNAL")) { if (authRequest->getMechanism() == "EXTERNAL") { getXMPPLayer()->writeElement(std::make_shared()); authenticated_ = true; getXMPPLayer()->resetParser(); } else { PLAINMessage plainMessage(authRequest->getMessage() ? *authRequest->getMessage() : createSafeByteArray("")); if (userRegistry_->isValidUserPassword(JID(plainMessage.getAuthenticationID(), getLocalJID().getDomain()), plainMessage.getPassword())) { getXMPPLayer()->writeElement(std::make_shared()); user_ = plainMessage.getAuthenticationID(); authenticated_ = true; getXMPPLayer()->resetParser(); } else { getXMPPLayer()->writeElement(std::shared_ptr(new AuthFailure)); finishSession(AuthenticationFailedError); } } } else { getXMPPLayer()->writeElement(std::shared_ptr(new AuthFailure)); finishSession(NoSupportedAuthMechanismsError); } } else if (IQ* iq = dynamic_cast(element.get())) { if (std::shared_ptr resourceBind = iq->getPayload()) { setRemoteJID(JID(user_, getLocalJID().getDomain(), resourceBind->getResource())); std::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); std::shared_ptr features(new StreamFeatures()); if (!authenticated_) { features->addAuthenticationMechanism("PLAIN"); if (allowSASLEXTERNAL) { features->addAuthenticationMechanism("EXTERNAL"); } } else { features->setHasResourceBind(); features->setHasSession(); } getXMPPLayer()->writeElement(features); } void ServerFromClientSession::setInitialized() { initialized = true; onSessionStarted(); } void ServerFromClientSession::setAllowSASLEXTERNAL() { allowSASLEXTERNAL = true; } }