10e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/* 20e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * libjingle 30e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Copyright 2004--2005, Google Inc. 40e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 50e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Redistribution and use in source and binary forms, with or without 60e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * modification, are permitted provided that the following conditions are met: 70e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 80e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 1. Redistributions of source code must retain the above copyright notice, 90e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * this list of conditions and the following disclaimer. 100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 2. Redistributions in binary form must reproduce the above copyright notice, 110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * this list of conditions and the following disclaimer in the documentation 120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * and/or other materials provided with the distribution. 130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 3. The name of the author may not be used to endorse or promote products 140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * derived from this software without specific prior written permission. 150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org */ 270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/xmpp/xmpplogintask.h" 290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include <string> 310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include <vector> 320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3313b2d035e2e7f2f18e3a4d3377bc1a09f43a4ff9buildbot@webrtc.org#include "webrtc/libjingle/xmllite/xmlelement.h" 340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/xmpp/constants.h" 350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/xmpp/jid.h" 360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/xmpp/saslmechanism.h" 370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/xmpp/xmppengineimpl.h" 38cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "webrtc/base/base64.h" 39cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "webrtc/base/common.h" 400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 412a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgusing rtc::ConstantLabel; 420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgnamespace buzz { 440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#ifdef _DEBUG 460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst ConstantLabel XmppLoginTask::LOGINTASK_STATES[] = { 470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org KLABEL(LOGINSTATE_INIT), 480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org KLABEL(LOGINSTATE_STREAMSTART_SENT), 490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org KLABEL(LOGINSTATE_STARTED_XMPP), 500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org KLABEL(LOGINSTATE_TLS_INIT), 510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org KLABEL(LOGINSTATE_AUTH_INIT), 520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org KLABEL(LOGINSTATE_BIND_INIT), 530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org KLABEL(LOGINSTATE_TLS_REQUESTED), 540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org KLABEL(LOGINSTATE_SASL_RUNNING), 550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org KLABEL(LOGINSTATE_BIND_REQUESTED), 560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org KLABEL(LOGINSTATE_SESSION_REQUESTED), 570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org KLABEL(LOGINSTATE_DONE), 580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LASTLABEL 590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}; 600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#endif // _DEBUG 610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgXmppLoginTask::XmppLoginTask(XmppEngineImpl * pctx) : 620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pctx_(pctx), 630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org authNeeded_(true), 640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org allowNonGoogleLogin_(true), 650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org state_(LOGINSTATE_INIT), 660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pelStanza_(NULL), 670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org isStart_(false), 680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iqId_(STR_EMPTY), 695c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org pelFeatures_(), 700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org fullJid_(STR_EMPTY), 710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org streamId_(STR_EMPTY), 720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pvecQueuedStanzas_(new std::vector<XmlElement *>()), 735c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org sasl_mech_() { 740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgXmppLoginTask::~XmppLoginTask() { 770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (size_t i = 0; i < pvecQueuedStanzas_->size(); i += 1) 780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org delete (*pvecQueuedStanzas_)[i]; 790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid 820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgXmppLoginTask::IncomingStanza(const XmlElement *element, bool isStart) { 830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pelStanza_ = element; 840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org isStart_ = isStart; 850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org Advance(); 860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pelStanza_ = NULL; 870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org isStart_ = false; 880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst XmlElement * 910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgXmppLoginTask::NextStanza() { 920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const XmlElement * result = pelStanza_; 930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pelStanza_ = NULL; 940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return result; 950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool 980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgXmppLoginTask::Advance() { 990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (;;) { 1010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const XmlElement * element = NULL; 1030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#if _DEBUG 1050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_VERBOSE) << "XmppLoginTask::Advance - " 1062a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org << rtc::ErrorName(state_, LOGINTASK_STATES); 1070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#endif // _DEBUG 1080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org switch (state_) { 1100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case LOGINSTATE_INIT: { 1120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pctx_->RaiseReset(); 1130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pelFeatures_.reset(NULL); 1140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // The proper domain to verify against is the real underlying 1160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // domain - i.e., the domain that owns the JID. Our XmppEngineImpl 1170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // also allows matching against a proxy domain instead, if it is told 1180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // to do so - see the implementation of XmppEngineImpl::StartTls and 1190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // XmppEngine::SetTlsServerDomain to see how you can use that feature 1200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pctx_->InternalSendStart(pctx_->user_jid_.domain()); 1210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org state_ = LOGINSTATE_STREAMSTART_SENT; 1220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 1230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case LOGINSTATE_STREAMSTART_SENT: { 1260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (NULL == (element = NextStanza())) 1270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 1280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!isStart_ || !HandleStartStream(element)) 1300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return Failure(XmppEngine::ERROR_VERSION); 1310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org state_ = LOGINSTATE_STARTED_XMPP; 1330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 1340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case LOGINSTATE_STARTED_XMPP: { 1370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (NULL == (element = NextStanza())) 1380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 1390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!HandleFeatures(element)) 1410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return Failure(XmppEngine::ERROR_VERSION); 1420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool tls_present = (GetFeature(QN_TLS_STARTTLS) != NULL); 1440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Error if TLS required but not present. 1450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (pctx_->tls_option_ == buzz::TLS_REQUIRED && !tls_present) { 1460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return Failure(XmppEngine::ERROR_TLS); 1470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Use TLS if required or enabled, and also available 1490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if ((pctx_->tls_option_ == buzz::TLS_REQUIRED || 1500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pctx_->tls_option_ == buzz::TLS_ENABLED) && tls_present) { 1510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org state_ = LOGINSTATE_TLS_INIT; 1520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org continue; 1530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (authNeeded_) { 1560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org state_ = LOGINSTATE_AUTH_INIT; 1570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org continue; 1580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org state_ = LOGINSTATE_BIND_INIT; 1610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org continue; 1620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case LOGINSTATE_TLS_INIT: { 1650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const XmlElement * pelTls = GetFeature(QN_TLS_STARTTLS); 1660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!pelTls) 1670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return Failure(XmppEngine::ERROR_TLS); 1680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org XmlElement el(QN_TLS_STARTTLS, true); 1700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pctx_->InternalSendStanza(&el); 1710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org state_ = LOGINSTATE_TLS_REQUESTED; 1720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org continue; 1730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case LOGINSTATE_TLS_REQUESTED: { 1760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (NULL == (element = NextStanza())) 1770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 1780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (element->Name() != QN_TLS_PROCEED) 1790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return Failure(XmppEngine::ERROR_TLS); 1800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // The proper domain to verify against is the real underlying 1820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // domain - i.e., the domain that owns the JID. Our XmppEngineImpl 1830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // also allows matching against a proxy domain instead, if it is told 1840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // to do so - see the implementation of XmppEngineImpl::StartTls and 1850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // XmppEngine::SetTlsServerDomain to see how you can use that feature 1860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pctx_->StartTls(pctx_->user_jid_.domain()); 1870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pctx_->tls_option_ = buzz::TLS_ENABLED; 1880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org state_ = LOGINSTATE_INIT; 1890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org continue; 1900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case LOGINSTATE_AUTH_INIT: { 1930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const XmlElement * pelSaslAuth = GetFeature(QN_SASL_MECHANISMS); 1940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!pelSaslAuth) { 1950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return Failure(XmppEngine::ERROR_AUTH); 1960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Collect together the SASL auth mechanisms presented by the server 1990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::vector<std::string> mechanisms; 2000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (const XmlElement * pelMech = 2010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pelSaslAuth->FirstNamed(QN_SASL_MECHANISM); 2020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pelMech; 2030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pelMech = pelMech->NextNamed(QN_SASL_MECHANISM)) { 2040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org mechanisms.push_back(pelMech->BodyText()); 2060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Given all the mechanisms, choose the best 2090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::string choice(pctx_->ChooseBestSaslMechanism(mechanisms, pctx_->IsEncrypted())); 2100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (choice.empty()) { 2110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return Failure(XmppEngine::ERROR_AUTH); 2120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // No recognized auth mechanism - that's an error 2150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org sasl_mech_.reset(pctx_->GetSaslMechanism(choice)); 2160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!sasl_mech_) { 2170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return Failure(XmppEngine::ERROR_AUTH); 2180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // OK, let's start it. 2210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org XmlElement * auth = sasl_mech_->StartSaslAuth(); 2220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (auth == NULL) { 2230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return Failure(XmppEngine::ERROR_AUTH); 2240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (allowNonGoogleLogin_) { 2260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Setting the following two attributes is required to support 2270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // non-google ids. 2280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Allow login with non-google id accounts. 2300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org auth->SetAttr(QN_GOOGLE_ALLOW_NON_GOOGLE_ID_XMPP_LOGIN, "true"); 2310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Allow login with either the non-google id or the friendly email. 2330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org auth->SetAttr(QN_GOOGLE_AUTH_CLIENT_USES_FULL_BIND_RESULT, "true"); 2340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pctx_->InternalSendStanza(auth); 2370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org delete auth; 2380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org state_ = LOGINSTATE_SASL_RUNNING; 2390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org continue; 2400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case LOGINSTATE_SASL_RUNNING: { 2430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (NULL == (element = NextStanza())) 2440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 2450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (element->Name().Namespace() != NS_SASL) 2460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return Failure(XmppEngine::ERROR_AUTH); 2470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (element->Name() == QN_SASL_CHALLENGE) { 2480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org XmlElement * response = sasl_mech_->HandleSaslChallenge(element); 2490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (response == NULL) { 2500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return Failure(XmppEngine::ERROR_AUTH); 2510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pctx_->InternalSendStanza(response); 2530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org delete response; 2540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org state_ = LOGINSTATE_SASL_RUNNING; 2550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org continue; 2560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (element->Name() != QN_SASL_SUCCESS) { 2580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return Failure(XmppEngine::ERROR_UNAUTHORIZED); 2590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Authenticated! 2620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org authNeeded_ = false; 2630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org state_ = LOGINSTATE_INIT; 2640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org continue; 2650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case LOGINSTATE_BIND_INIT: { 2680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const XmlElement * pelBindFeature = GetFeature(QN_BIND_BIND); 2690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const XmlElement * pelSessionFeature = GetFeature(QN_SESSION_SESSION); 2700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!pelBindFeature || !pelSessionFeature) 2710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return Failure(XmppEngine::ERROR_BIND); 2720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org XmlElement iq(QN_IQ); 2740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iq.AddAttr(QN_TYPE, "set"); 2750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iqId_ = pctx_->NextId(); 2770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iq.AddAttr(QN_ID, iqId_); 2780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iq.AddElement(new XmlElement(QN_BIND_BIND, true)); 2790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (pctx_->requested_resource_ != STR_EMPTY) { 2810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iq.AddElement(new XmlElement(QN_BIND_RESOURCE), 1); 2820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iq.AddText(pctx_->requested_resource_, 2); 2830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pctx_->InternalSendStanza(&iq); 2850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org state_ = LOGINSTATE_BIND_REQUESTED; 2860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org continue; 2870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case LOGINSTATE_BIND_REQUESTED: { 2900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (NULL == (element = NextStanza())) 2910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 2920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (element->Name() != QN_IQ || element->Attr(QN_ID) != iqId_ || 2940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org element->Attr(QN_TYPE) == "get" || element->Attr(QN_TYPE) == "set") 2950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 2960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (element->Attr(QN_TYPE) != "result" || element->FirstElement() == NULL || 2980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org element->FirstElement()->Name() != QN_BIND_BIND) 2990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return Failure(XmppEngine::ERROR_BIND); 3000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org fullJid_ = Jid(element->FirstElement()->TextNamed(QN_BIND_JID)); 3020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!fullJid_.IsFull()) { 3030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return Failure(XmppEngine::ERROR_BIND); 3040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // now request session 3070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org XmlElement iq(QN_IQ); 3080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iq.AddAttr(QN_TYPE, "set"); 3090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iqId_ = pctx_->NextId(); 3110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iq.AddAttr(QN_ID, iqId_); 3120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iq.AddElement(new XmlElement(QN_SESSION_SESSION, true)); 3130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pctx_->InternalSendStanza(&iq); 3140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org state_ = LOGINSTATE_SESSION_REQUESTED; 3160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org continue; 3170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case LOGINSTATE_SESSION_REQUESTED: { 3200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (NULL == (element = NextStanza())) 3210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 3220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (element->Name() != QN_IQ || element->Attr(QN_ID) != iqId_ || 3230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org element->Attr(QN_TYPE) == "get" || element->Attr(QN_TYPE) == "set") 3240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 3250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (element->Attr(QN_TYPE) != "result") 3270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return Failure(XmppEngine::ERROR_BIND); 3280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pctx_->SignalBound(fullJid_); 3300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org FlushQueuedStanzas(); 3310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org state_ = LOGINSTATE_DONE; 3320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 3330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case LOGINSTATE_DONE: 3360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 3370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool 3420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgXmppLoginTask::HandleStartStream(const XmlElement *element) { 3430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (element->Name() != QN_STREAM_STREAM) 3450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 3460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (element->Attr(QN_XMLNS) != "jabber:client") 3480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 3490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (element->Attr(QN_VERSION) != "1.0") 3510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 3520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!element->HasAttr(QN_ID)) 3540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 3550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org streamId_ = element->Attr(QN_ID); 3570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 3590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool 3620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgXmppLoginTask::HandleFeatures(const XmlElement *element) { 3630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (element->Name() != QN_STREAM_FEATURES) 3640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 3650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pelFeatures_.reset(new XmlElement(*element)); 3670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 3680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst XmlElement * 3710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgXmppLoginTask::GetFeature(const QName & name) { 3720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return pelFeatures_->FirstNamed(name); 3730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool 3760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgXmppLoginTask::Failure(XmppEngine::Error reason) { 3770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org state_ = LOGINSTATE_DONE; 3780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pctx_->SignalError(reason, 0); 3790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 3800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid 3830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgXmppLoginTask::OutgoingStanza(const XmlElement * element) { 3840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org XmlElement * pelCopy = new XmlElement(*element); 3850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pvecQueuedStanzas_->push_back(pelCopy); 3860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid 3890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgXmppLoginTask::FlushQueuedStanzas() { 3900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (size_t i = 0; i < pvecQueuedStanzas_->size(); i += 1) { 3910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pctx_->InternalSendStanza((*pvecQueuedStanzas_)[i]); 3920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org delete (*pvecQueuedStanzas_)[i]; 3930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pvecQueuedStanzas_->clear(); 3950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 398