15976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/* 25976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * libjingle 35976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Copyright 2004--2005, Google Inc. 45976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 55976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Redistribution and use in source and binary forms, with or without 65976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * modification, are permitted provided that the following conditions are met: 75976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 85976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 1. Redistributions of source code must retain the above copyright notice, 95976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * this list of conditions and the following disclaimer. 105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 2. Redistributions in binary form must reproduce the above copyright notice, 115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * this list of conditions and the following disclaimer in the documentation 125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * and/or other materials provided with the distribution. 135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 3. The name of the author may not be used to endorse or promote products 145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * derived from this software without specific prior written permission. 155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org */ 275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/xmpp/xmpplogintask.h" 295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <string> 315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <vector> 325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/base64.h" 345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/common.h" 355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/xmllite/xmlelement.h" 365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/xmpp/constants.h" 375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/xmpp/jid.h" 385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/xmpp/saslmechanism.h" 395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/xmpp/xmppengineimpl.h" 405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgusing talk_base::ConstantLabel; 425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgnamespace buzz { 445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifdef _DEBUG 465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgconst ConstantLabel XmppLoginTask::LOGINTASK_STATES[] = { 475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org KLABEL(LOGINSTATE_INIT), 485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org KLABEL(LOGINSTATE_STREAMSTART_SENT), 495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org KLABEL(LOGINSTATE_STARTED_XMPP), 505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org KLABEL(LOGINSTATE_TLS_INIT), 515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org KLABEL(LOGINSTATE_AUTH_INIT), 525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org KLABEL(LOGINSTATE_BIND_INIT), 535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org KLABEL(LOGINSTATE_TLS_REQUESTED), 545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org KLABEL(LOGINSTATE_SASL_RUNNING), 555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org KLABEL(LOGINSTATE_BIND_REQUESTED), 565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org KLABEL(LOGINSTATE_SESSION_REQUESTED), 575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org KLABEL(LOGINSTATE_DONE), 585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LASTLABEL 595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}; 605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif // _DEBUG 615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgXmppLoginTask::XmppLoginTask(XmppEngineImpl * pctx) : 625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pctx_(pctx), 635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org authNeeded_(true), 645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org allowNonGoogleLogin_(true), 655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state_(LOGINSTATE_INIT), 665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pelStanza_(NULL), 675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org isStart_(false), 685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org iqId_(STR_EMPTY), 69582fe818e571fa2571267f5e369715188472f352wu@webrtc.org pelFeatures_(), 705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org fullJid_(STR_EMPTY), 715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org streamId_(STR_EMPTY), 725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pvecQueuedStanzas_(new std::vector<XmlElement *>()), 73582fe818e571fa2571267f5e369715188472f352wu@webrtc.org sasl_mech_() { 745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgXmppLoginTask::~XmppLoginTask() { 775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org for (size_t i = 0; i < pvecQueuedStanzas_->size(); i += 1) 785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org delete (*pvecQueuedStanzas_)[i]; 795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid 825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgXmppLoginTask::IncomingStanza(const XmlElement *element, bool isStart) { 835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pelStanza_ = element; 845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org isStart_ = isStart; 855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org Advance(); 865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pelStanza_ = NULL; 875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org isStart_ = false; 885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgconst XmlElement * 915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgXmppLoginTask::NextStanza() { 925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const XmlElement * result = pelStanza_; 935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pelStanza_ = NULL; 945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return result; 955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool 985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgXmppLoginTask::Advance() { 995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org for (;;) { 1015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const XmlElement * element = NULL; 1035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#if _DEBUG 1055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_VERBOSE) << "XmppLoginTask::Advance - " 1065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org << talk_base::ErrorName(state_, LOGINTASK_STATES); 1075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif // _DEBUG 1085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org switch (state_) { 1105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case LOGINSTATE_INIT: { 1125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pctx_->RaiseReset(); 1135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pelFeatures_.reset(NULL); 1145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // The proper domain to verify against is the real underlying 1165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // domain - i.e., the domain that owns the JID. Our XmppEngineImpl 1175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // also allows matching against a proxy domain instead, if it is told 1185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // to do so - see the implementation of XmppEngineImpl::StartTls and 1195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // XmppEngine::SetTlsServerDomain to see how you can use that feature 1205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pctx_->InternalSendStart(pctx_->user_jid_.domain()); 1215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state_ = LOGINSTATE_STREAMSTART_SENT; 1225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 1235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case LOGINSTATE_STREAMSTART_SENT: { 1265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (NULL == (element = NextStanza())) 1275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 1285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!isStart_ || !HandleStartStream(element)) 1305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return Failure(XmppEngine::ERROR_VERSION); 1315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state_ = LOGINSTATE_STARTED_XMPP; 1335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 1345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case LOGINSTATE_STARTED_XMPP: { 1375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (NULL == (element = NextStanza())) 1385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 1395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!HandleFeatures(element)) 1415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return Failure(XmppEngine::ERROR_VERSION); 1425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org bool tls_present = (GetFeature(QN_TLS_STARTTLS) != NULL); 1445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Error if TLS required but not present. 1455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (pctx_->tls_option_ == buzz::TLS_REQUIRED && !tls_present) { 1465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return Failure(XmppEngine::ERROR_TLS); 1475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Use TLS if required or enabled, and also available 1495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if ((pctx_->tls_option_ == buzz::TLS_REQUIRED || 1505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pctx_->tls_option_ == buzz::TLS_ENABLED) && tls_present) { 1515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state_ = LOGINSTATE_TLS_INIT; 1525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org continue; 1535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (authNeeded_) { 1565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state_ = LOGINSTATE_AUTH_INIT; 1575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org continue; 1585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state_ = LOGINSTATE_BIND_INIT; 1615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org continue; 1625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case LOGINSTATE_TLS_INIT: { 1655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const XmlElement * pelTls = GetFeature(QN_TLS_STARTTLS); 1665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!pelTls) 1675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return Failure(XmppEngine::ERROR_TLS); 1685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org XmlElement el(QN_TLS_STARTTLS, true); 1705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pctx_->InternalSendStanza(&el); 1715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state_ = LOGINSTATE_TLS_REQUESTED; 1725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org continue; 1735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case LOGINSTATE_TLS_REQUESTED: { 1765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (NULL == (element = NextStanza())) 1775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 1785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (element->Name() != QN_TLS_PROCEED) 1795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return Failure(XmppEngine::ERROR_TLS); 1805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // The proper domain to verify against is the real underlying 1825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // domain - i.e., the domain that owns the JID. Our XmppEngineImpl 1835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // also allows matching against a proxy domain instead, if it is told 1845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // to do so - see the implementation of XmppEngineImpl::StartTls and 1855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // XmppEngine::SetTlsServerDomain to see how you can use that feature 1865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pctx_->StartTls(pctx_->user_jid_.domain()); 1875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pctx_->tls_option_ = buzz::TLS_ENABLED; 1885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state_ = LOGINSTATE_INIT; 1895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org continue; 1905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case LOGINSTATE_AUTH_INIT: { 1935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const XmlElement * pelSaslAuth = GetFeature(QN_SASL_MECHANISMS); 1945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!pelSaslAuth) { 1955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return Failure(XmppEngine::ERROR_AUTH); 1965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Collect together the SASL auth mechanisms presented by the server 1995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::vector<std::string> mechanisms; 2005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org for (const XmlElement * pelMech = 2015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pelSaslAuth->FirstNamed(QN_SASL_MECHANISM); 2025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pelMech; 2035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pelMech = pelMech->NextNamed(QN_SASL_MECHANISM)) { 2045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org mechanisms.push_back(pelMech->BodyText()); 2065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Given all the mechanisms, choose the best 2095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::string choice(pctx_->ChooseBestSaslMechanism(mechanisms, pctx_->IsEncrypted())); 2105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (choice.empty()) { 2115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return Failure(XmppEngine::ERROR_AUTH); 2125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // No recognized auth mechanism - that's an error 2155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org sasl_mech_.reset(pctx_->GetSaslMechanism(choice)); 2165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!sasl_mech_) { 2175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return Failure(XmppEngine::ERROR_AUTH); 2185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // OK, let's start it. 2215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org XmlElement * auth = sasl_mech_->StartSaslAuth(); 2225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (auth == NULL) { 2235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return Failure(XmppEngine::ERROR_AUTH); 2245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (allowNonGoogleLogin_) { 2265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Setting the following two attributes is required to support 2275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // non-google ids. 2285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Allow login with non-google id accounts. 2305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org auth->SetAttr(QN_GOOGLE_ALLOW_NON_GOOGLE_ID_XMPP_LOGIN, "true"); 2315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Allow login with either the non-google id or the friendly email. 2335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org auth->SetAttr(QN_GOOGLE_AUTH_CLIENT_USES_FULL_BIND_RESULT, "true"); 2345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pctx_->InternalSendStanza(auth); 2375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org delete auth; 2385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state_ = LOGINSTATE_SASL_RUNNING; 2395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org continue; 2405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case LOGINSTATE_SASL_RUNNING: { 2435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (NULL == (element = NextStanza())) 2445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 2455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (element->Name().Namespace() != NS_SASL) 2465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return Failure(XmppEngine::ERROR_AUTH); 2475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (element->Name() == QN_SASL_CHALLENGE) { 2485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org XmlElement * response = sasl_mech_->HandleSaslChallenge(element); 2495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (response == NULL) { 2505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return Failure(XmppEngine::ERROR_AUTH); 2515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pctx_->InternalSendStanza(response); 2535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org delete response; 2545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state_ = LOGINSTATE_SASL_RUNNING; 2555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org continue; 2565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (element->Name() != QN_SASL_SUCCESS) { 2585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return Failure(XmppEngine::ERROR_UNAUTHORIZED); 2595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Authenticated! 2625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org authNeeded_ = false; 2635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state_ = LOGINSTATE_INIT; 2645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org continue; 2655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case LOGINSTATE_BIND_INIT: { 2685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const XmlElement * pelBindFeature = GetFeature(QN_BIND_BIND); 2695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const XmlElement * pelSessionFeature = GetFeature(QN_SESSION_SESSION); 2705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!pelBindFeature || !pelSessionFeature) 2715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return Failure(XmppEngine::ERROR_BIND); 2725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org XmlElement iq(QN_IQ); 2745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org iq.AddAttr(QN_TYPE, "set"); 2755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org iqId_ = pctx_->NextId(); 2775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org iq.AddAttr(QN_ID, iqId_); 2785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org iq.AddElement(new XmlElement(QN_BIND_BIND, true)); 2795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (pctx_->requested_resource_ != STR_EMPTY) { 2815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org iq.AddElement(new XmlElement(QN_BIND_RESOURCE), 1); 2825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org iq.AddText(pctx_->requested_resource_, 2); 2835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pctx_->InternalSendStanza(&iq); 2855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state_ = LOGINSTATE_BIND_REQUESTED; 2865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org continue; 2875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case LOGINSTATE_BIND_REQUESTED: { 2905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (NULL == (element = NextStanza())) 2915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 2925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (element->Name() != QN_IQ || element->Attr(QN_ID) != iqId_ || 2945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org element->Attr(QN_TYPE) == "get" || element->Attr(QN_TYPE) == "set") 2955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 2965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (element->Attr(QN_TYPE) != "result" || element->FirstElement() == NULL || 2985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org element->FirstElement()->Name() != QN_BIND_BIND) 2995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return Failure(XmppEngine::ERROR_BIND); 3005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org fullJid_ = Jid(element->FirstElement()->TextNamed(QN_BIND_JID)); 3025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!fullJid_.IsFull()) { 3035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return Failure(XmppEngine::ERROR_BIND); 3045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // now request session 3075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org XmlElement iq(QN_IQ); 3085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org iq.AddAttr(QN_TYPE, "set"); 3095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org iqId_ = pctx_->NextId(); 3115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org iq.AddAttr(QN_ID, iqId_); 3125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org iq.AddElement(new XmlElement(QN_SESSION_SESSION, true)); 3135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pctx_->InternalSendStanza(&iq); 3145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state_ = LOGINSTATE_SESSION_REQUESTED; 3165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org continue; 3175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case LOGINSTATE_SESSION_REQUESTED: { 3205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (NULL == (element = NextStanza())) 3215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 3225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (element->Name() != QN_IQ || element->Attr(QN_ID) != iqId_ || 3235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org element->Attr(QN_TYPE) == "get" || element->Attr(QN_TYPE) == "set") 3245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 3255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (element->Attr(QN_TYPE) != "result") 3275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return Failure(XmppEngine::ERROR_BIND); 3285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pctx_->SignalBound(fullJid_); 3305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org FlushQueuedStanzas(); 3315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state_ = LOGINSTATE_DONE; 3325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 3335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case LOGINSTATE_DONE: 3365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 3375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 3405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool 3425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgXmppLoginTask::HandleStartStream(const XmlElement *element) { 3435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (element->Name() != QN_STREAM_STREAM) 3455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 3465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (element->Attr(QN_XMLNS) != "jabber:client") 3485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 3495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (element->Attr(QN_VERSION) != "1.0") 3515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 3525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!element->HasAttr(QN_ID)) 3545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 3555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org streamId_ = element->Attr(QN_ID); 3575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 3595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 3605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool 3625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgXmppLoginTask::HandleFeatures(const XmlElement *element) { 3635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (element->Name() != QN_STREAM_FEATURES) 3645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 3655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pelFeatures_.reset(new XmlElement(*element)); 3675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 3685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 3695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgconst XmlElement * 3715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgXmppLoginTask::GetFeature(const QName & name) { 3725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return pelFeatures_->FirstNamed(name); 3735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 3745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool 3765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgXmppLoginTask::Failure(XmppEngine::Error reason) { 3775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state_ = LOGINSTATE_DONE; 3785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pctx_->SignalError(reason, 0); 3795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 3805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 3815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid 3835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgXmppLoginTask::OutgoingStanza(const XmlElement * element) { 3845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org XmlElement * pelCopy = new XmlElement(*element); 3855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pvecQueuedStanzas_->push_back(pelCopy); 3865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 3875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid 3895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgXmppLoginTask::FlushQueuedStanzas() { 3905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org for (size_t i = 0; i < pvecQueuedStanzas_->size(); i += 1) { 3915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pctx_->InternalSendStanza((*pvecQueuedStanzas_)[i]); 3925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org delete (*pvecQueuedStanzas_)[i]; 3935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pvecQueuedStanzas_->clear(); 3955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 3965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 398