1269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org/* 2269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org * Copyright 2004 The WebRTC Project Authors. All rights reserved. 3269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org * 4269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org * Use of this source code is governed by a BSD-style license 5269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org * that can be found in the LICENSE file in the root of the source 6269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org * tree. An additional intellectual property rights grant can be found 7269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org * in the file PATENTS. All contributing project authors may 8269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org */ 10269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 11269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/libjingle/xmpp/xmpplogintask.h" 12269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 13269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include <string> 14269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include <vector> 15269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 16269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/libjingle/xmllite/xmlelement.h" 17269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/libjingle/xmpp/constants.h" 18269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/libjingle/xmpp/jid.h" 19269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/libjingle/xmpp/saslmechanism.h" 20269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/libjingle/xmpp/xmppengineimpl.h" 21269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/base64.h" 22269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/common.h" 23269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 24269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgusing rtc::ConstantLabel; 25269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 26269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgnamespace buzz { 27269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 28a41ab9326c8f0f7eb738e5d51a239a2b9e276361tfarina#if !defined(NDEBUG) 29269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgconst ConstantLabel XmppLoginTask::LOGINTASK_STATES[] = { 30269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org KLABEL(LOGINSTATE_INIT), 31269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org KLABEL(LOGINSTATE_STREAMSTART_SENT), 32269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org KLABEL(LOGINSTATE_STARTED_XMPP), 33269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org KLABEL(LOGINSTATE_TLS_INIT), 34269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org KLABEL(LOGINSTATE_AUTH_INIT), 35269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org KLABEL(LOGINSTATE_BIND_INIT), 36269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org KLABEL(LOGINSTATE_TLS_REQUESTED), 37269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org KLABEL(LOGINSTATE_SASL_RUNNING), 38269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org KLABEL(LOGINSTATE_BIND_REQUESTED), 39269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org KLABEL(LOGINSTATE_SESSION_REQUESTED), 40269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org KLABEL(LOGINSTATE_DONE), 41269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org LASTLABEL 42269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}; 43a41ab9326c8f0f7eb738e5d51a239a2b9e276361tfarina#endif 44269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgXmppLoginTask::XmppLoginTask(XmppEngineImpl * pctx) : 45269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pctx_(pctx), 46269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org authNeeded_(true), 47269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org allowNonGoogleLogin_(true), 48269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org state_(LOGINSTATE_INIT), 49269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pelStanza_(NULL), 50269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org isStart_(false), 51269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org iqId_(STR_EMPTY), 52269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pelFeatures_(), 53269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org fullJid_(STR_EMPTY), 54269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org streamId_(STR_EMPTY), 55269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pvecQueuedStanzas_(new std::vector<XmlElement *>()), 56269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org sasl_mech_() { 57269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org} 58269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 59269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgXmppLoginTask::~XmppLoginTask() { 60269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org for (size_t i = 0; i < pvecQueuedStanzas_->size(); i += 1) 61269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org delete (*pvecQueuedStanzas_)[i]; 62269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org} 63269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 64269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgvoid 65269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgXmppLoginTask::IncomingStanza(const XmlElement *element, bool isStart) { 66269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pelStanza_ = element; 67269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org isStart_ = isStart; 68269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org Advance(); 69269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pelStanza_ = NULL; 70269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org isStart_ = false; 71269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org} 72269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 73269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgconst XmlElement * 74269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgXmppLoginTask::NextStanza() { 75269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org const XmlElement * result = pelStanza_; 76269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pelStanza_ = NULL; 77269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return result; 78269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org} 79269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 80269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgbool 81269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgXmppLoginTask::Advance() { 82269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 83269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org for (;;) { 84269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 85269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org const XmlElement * element = NULL; 86269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 87a41ab9326c8f0f7eb738e5d51a239a2b9e276361tfarina#if !defined(NDEBUG) 88269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org LOG(LS_VERBOSE) << "XmppLoginTask::Advance - " 89269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org << rtc::ErrorName(state_, LOGINTASK_STATES); 90a41ab9326c8f0f7eb738e5d51a239a2b9e276361tfarina#endif 91269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 92269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org switch (state_) { 93269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 94269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org case LOGINSTATE_INIT: { 95269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pctx_->RaiseReset(); 96269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pelFeatures_.reset(NULL); 97269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 98269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org // The proper domain to verify against is the real underlying 99269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org // domain - i.e., the domain that owns the JID. Our XmppEngineImpl 100269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org // also allows matching against a proxy domain instead, if it is told 101269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org // to do so - see the implementation of XmppEngineImpl::StartTls and 102269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org // XmppEngine::SetTlsServerDomain to see how you can use that feature 103269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pctx_->InternalSendStart(pctx_->user_jid_.domain()); 104269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org state_ = LOGINSTATE_STREAMSTART_SENT; 105269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org break; 106269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 107269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 108269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org case LOGINSTATE_STREAMSTART_SENT: { 109269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (NULL == (element = NextStanza())) 110269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return true; 111269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 112269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (!isStart_ || !HandleStartStream(element)) 113269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return Failure(XmppEngine::ERROR_VERSION); 114269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 115269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org state_ = LOGINSTATE_STARTED_XMPP; 116269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return true; 117269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 118269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 119269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org case LOGINSTATE_STARTED_XMPP: { 120269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (NULL == (element = NextStanza())) 121269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return true; 122269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 123269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (!HandleFeatures(element)) 124269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return Failure(XmppEngine::ERROR_VERSION); 125269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 126269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org bool tls_present = (GetFeature(QN_TLS_STARTTLS) != NULL); 127269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org // Error if TLS required but not present. 128269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (pctx_->tls_option_ == buzz::TLS_REQUIRED && !tls_present) { 129269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return Failure(XmppEngine::ERROR_TLS); 130269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 131269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org // Use TLS if required or enabled, and also available 132269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if ((pctx_->tls_option_ == buzz::TLS_REQUIRED || 133269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pctx_->tls_option_ == buzz::TLS_ENABLED) && tls_present) { 134269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org state_ = LOGINSTATE_TLS_INIT; 135269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org continue; 136269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 137269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 138269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (authNeeded_) { 139269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org state_ = LOGINSTATE_AUTH_INIT; 140269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org continue; 141269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 142269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 143269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org state_ = LOGINSTATE_BIND_INIT; 144269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org continue; 145269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 146269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 147269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org case LOGINSTATE_TLS_INIT: { 148269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org const XmlElement * pelTls = GetFeature(QN_TLS_STARTTLS); 149269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (!pelTls) 150269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return Failure(XmppEngine::ERROR_TLS); 151269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 152269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org XmlElement el(QN_TLS_STARTTLS, true); 153269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pctx_->InternalSendStanza(&el); 154269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org state_ = LOGINSTATE_TLS_REQUESTED; 155269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org continue; 156269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 157269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 158269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org case LOGINSTATE_TLS_REQUESTED: { 159269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (NULL == (element = NextStanza())) 160269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return true; 161269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (element->Name() != QN_TLS_PROCEED) 162269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return Failure(XmppEngine::ERROR_TLS); 163269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 164269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org // The proper domain to verify against is the real underlying 165269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org // domain - i.e., the domain that owns the JID. Our XmppEngineImpl 166269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org // also allows matching against a proxy domain instead, if it is told 167269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org // to do so - see the implementation of XmppEngineImpl::StartTls and 168269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org // XmppEngine::SetTlsServerDomain to see how you can use that feature 169269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pctx_->StartTls(pctx_->user_jid_.domain()); 170269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pctx_->tls_option_ = buzz::TLS_ENABLED; 171269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org state_ = LOGINSTATE_INIT; 172269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org continue; 173269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 174269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 175269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org case LOGINSTATE_AUTH_INIT: { 176269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org const XmlElement * pelSaslAuth = GetFeature(QN_SASL_MECHANISMS); 177269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (!pelSaslAuth) { 178269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return Failure(XmppEngine::ERROR_AUTH); 179269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 180269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 181269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org // Collect together the SASL auth mechanisms presented by the server 182269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org std::vector<std::string> mechanisms; 183269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org for (const XmlElement * pelMech = 184269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pelSaslAuth->FirstNamed(QN_SASL_MECHANISM); 185269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pelMech; 186269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pelMech = pelMech->NextNamed(QN_SASL_MECHANISM)) { 187269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 188269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org mechanisms.push_back(pelMech->BodyText()); 189269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 190269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 191269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org // Given all the mechanisms, choose the best 192269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org std::string choice(pctx_->ChooseBestSaslMechanism(mechanisms, pctx_->IsEncrypted())); 193269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (choice.empty()) { 194269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return Failure(XmppEngine::ERROR_AUTH); 195269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 196269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 197269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org // No recognized auth mechanism - that's an error 198269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org sasl_mech_.reset(pctx_->GetSaslMechanism(choice)); 199269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (!sasl_mech_) { 200269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return Failure(XmppEngine::ERROR_AUTH); 201269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 202269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 203269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org // OK, let's start it. 204269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org XmlElement * auth = sasl_mech_->StartSaslAuth(); 205269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (auth == NULL) { 206269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return Failure(XmppEngine::ERROR_AUTH); 207269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 208269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (allowNonGoogleLogin_) { 209269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org // Setting the following two attributes is required to support 210269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org // non-google ids. 211269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 212269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org // Allow login with non-google id accounts. 213269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org auth->SetAttr(QN_GOOGLE_ALLOW_NON_GOOGLE_ID_XMPP_LOGIN, "true"); 214269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 215269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org // Allow login with either the non-google id or the friendly email. 216269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org auth->SetAttr(QN_GOOGLE_AUTH_CLIENT_USES_FULL_BIND_RESULT, "true"); 217269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 218269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 219269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pctx_->InternalSendStanza(auth); 220269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org delete auth; 221269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org state_ = LOGINSTATE_SASL_RUNNING; 222269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org continue; 223269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 224269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 225269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org case LOGINSTATE_SASL_RUNNING: { 226269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (NULL == (element = NextStanza())) 227269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return true; 228269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (element->Name().Namespace() != NS_SASL) 229269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return Failure(XmppEngine::ERROR_AUTH); 230269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (element->Name() == QN_SASL_CHALLENGE) { 231269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org XmlElement * response = sasl_mech_->HandleSaslChallenge(element); 232269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (response == NULL) { 233269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return Failure(XmppEngine::ERROR_AUTH); 234269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 235269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pctx_->InternalSendStanza(response); 236269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org delete response; 237269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org state_ = LOGINSTATE_SASL_RUNNING; 238269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org continue; 239269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 240269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (element->Name() != QN_SASL_SUCCESS) { 241269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return Failure(XmppEngine::ERROR_UNAUTHORIZED); 242269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 243269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 244269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org // Authenticated! 245269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org authNeeded_ = false; 246269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org state_ = LOGINSTATE_INIT; 247269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org continue; 248269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 249269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 250269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org case LOGINSTATE_BIND_INIT: { 251269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org const XmlElement * pelBindFeature = GetFeature(QN_BIND_BIND); 252269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org const XmlElement * pelSessionFeature = GetFeature(QN_SESSION_SESSION); 253269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (!pelBindFeature || !pelSessionFeature) 254269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return Failure(XmppEngine::ERROR_BIND); 255269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 256269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org XmlElement iq(QN_IQ); 257269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org iq.AddAttr(QN_TYPE, "set"); 258269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 259269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org iqId_ = pctx_->NextId(); 260269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org iq.AddAttr(QN_ID, iqId_); 261269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org iq.AddElement(new XmlElement(QN_BIND_BIND, true)); 262269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 263269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (pctx_->requested_resource_ != STR_EMPTY) { 264269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org iq.AddElement(new XmlElement(QN_BIND_RESOURCE), 1); 265269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org iq.AddText(pctx_->requested_resource_, 2); 266269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 267269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pctx_->InternalSendStanza(&iq); 268269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org state_ = LOGINSTATE_BIND_REQUESTED; 269269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org continue; 270269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 271269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 272269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org case LOGINSTATE_BIND_REQUESTED: { 273269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (NULL == (element = NextStanza())) 274269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return true; 275269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 276269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (element->Name() != QN_IQ || element->Attr(QN_ID) != iqId_ || 277269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org element->Attr(QN_TYPE) == "get" || element->Attr(QN_TYPE) == "set") 278269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return true; 279269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 280269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (element->Attr(QN_TYPE) != "result" || element->FirstElement() == NULL || 281269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org element->FirstElement()->Name() != QN_BIND_BIND) 282269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return Failure(XmppEngine::ERROR_BIND); 283269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 284269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org fullJid_ = Jid(element->FirstElement()->TextNamed(QN_BIND_JID)); 285269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (!fullJid_.IsFull()) { 286269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return Failure(XmppEngine::ERROR_BIND); 287269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 288269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 289269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org // now request session 290269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org XmlElement iq(QN_IQ); 291269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org iq.AddAttr(QN_TYPE, "set"); 292269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 293269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org iqId_ = pctx_->NextId(); 294269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org iq.AddAttr(QN_ID, iqId_); 295269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org iq.AddElement(new XmlElement(QN_SESSION_SESSION, true)); 296269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pctx_->InternalSendStanza(&iq); 297269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 298269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org state_ = LOGINSTATE_SESSION_REQUESTED; 299269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org continue; 300269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 301269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 302269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org case LOGINSTATE_SESSION_REQUESTED: { 303269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (NULL == (element = NextStanza())) 304269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return true; 305269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (element->Name() != QN_IQ || element->Attr(QN_ID) != iqId_ || 306269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org element->Attr(QN_TYPE) == "get" || element->Attr(QN_TYPE) == "set") 307269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return false; 308269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 309269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (element->Attr(QN_TYPE) != "result") 310269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return Failure(XmppEngine::ERROR_BIND); 311269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 312269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pctx_->SignalBound(fullJid_); 313269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org FlushQueuedStanzas(); 314269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org state_ = LOGINSTATE_DONE; 315269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return true; 316269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 317269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 318269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org case LOGINSTATE_DONE: 319269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return false; 320269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 321269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 322269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org} 323269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 324269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgbool 325269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgXmppLoginTask::HandleStartStream(const XmlElement *element) { 326269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 327269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (element->Name() != QN_STREAM_STREAM) 328269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return false; 329269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 330269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (element->Attr(QN_XMLNS) != "jabber:client") 331269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return false; 332269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 333269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (element->Attr(QN_VERSION) != "1.0") 334269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return false; 335269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 336269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (!element->HasAttr(QN_ID)) 337269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return false; 338269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 339269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org streamId_ = element->Attr(QN_ID); 340269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 341269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return true; 342269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org} 343269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 344269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgbool 345269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgXmppLoginTask::HandleFeatures(const XmlElement *element) { 346269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (element->Name() != QN_STREAM_FEATURES) 347269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return false; 348269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 349269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pelFeatures_.reset(new XmlElement(*element)); 350269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return true; 351269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org} 352269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 353269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgconst XmlElement * 354269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgXmppLoginTask::GetFeature(const QName & name) { 355269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return pelFeatures_->FirstNamed(name); 356269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org} 357269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 358269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgbool 359269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgXmppLoginTask::Failure(XmppEngine::Error reason) { 360269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org state_ = LOGINSTATE_DONE; 361269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pctx_->SignalError(reason, 0); 362269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return false; 363269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org} 364269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 365269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgvoid 366269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgXmppLoginTask::OutgoingStanza(const XmlElement * element) { 367269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org XmlElement * pelCopy = new XmlElement(*element); 368269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pvecQueuedStanzas_->push_back(pelCopy); 369269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org} 370269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 371269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgvoid 372269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgXmppLoginTask::FlushQueuedStanzas() { 373269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org for (size_t i = 0; i < pvecQueuedStanzas_->size(); i += 1) { 374269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pctx_->InternalSendStanza((*pvecQueuedStanzas_)[i]); 375269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org delete (*pvecQueuedStanzas_)[i]; 376269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 377269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pvecQueuedStanzas_->clear(); 378269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org} 379269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 380269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org} 381