11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved. 21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be 31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file. 41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci'use strict'; 61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/** @suppress {duplicate} */ 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivar remoting = remoting || {}; 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/** 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * XmppLoginHandler handles authentication handshake for XmppConnection. It 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * receives incoming data using onDataReceived(), calls |sendMessageCallback| 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * to send outgoing messages and calls |onHandshakeDoneCallback| after 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * authentication is finished successfully or |onErrorCallback| on error. 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * See RFC3920 for description of XMPP and authentication handshake. 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @param {string} server Domain name of the server we are connecting to. 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @param {string} username Username. 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @param {string} authToken OAuth2 token. 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @param {function(string):void} sendMessageCallback Callback to call to send 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * a message. 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @param {function():void} startTlsCallback Callback to call to start TLS on 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * the underlying socket. 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @param {function(string, remoting.XmppStreamParser):void} 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * onHandshakeDoneCallback Callback to call after authentication is 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * completed successfully 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @param {function(remoting.Error, string):void} onErrorCallback Callback to 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * call on error. Can be called at any point during lifetime of connection. 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @constructor 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci */ 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciremoting.XmppLoginHandler = function(server, 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci username, 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci authToken, 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci sendMessageCallback, 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci startTlsCallback, 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci onHandshakeDoneCallback, 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci onErrorCallback) { 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /** @private */ 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.server_ = server; 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /** @private */ 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.username_ = username; 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /** @private */ 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.authToken_ = authToken; 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /** @private */ 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.sendMessageCallback_ = sendMessageCallback; 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /** @private */ 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.startTlsCallback_ = startTlsCallback; 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /** @private */ 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.onHandshakeDoneCallback_ = onHandshakeDoneCallback; 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /** @private */ 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.onErrorCallback_ = onErrorCallback; 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /** @private */ 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.state_ = remoting.XmppLoginHandler.State.INIT; 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /** @private */ 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.jid_ = ''; 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /** @type {remoting.XmppStreamParser} @private */ 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.streamParser_ = null; 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/** 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * States the handshake goes through. States are iterated from INIT to DONE 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * sequentially, except for ERROR state which may be accepted at any point. 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * Following messages are sent/received in each state: 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * INIT 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * client -> server: Stream header 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * client -> server: <starttls> 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * WAIT_STREAM_HEADER 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * client <- server: Stream header with list of supported features which 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * should include starttls. 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * WAIT_STARTTLS_RESPONSE 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * client <- server: <proceed> 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * STARTING_TLS 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * TLS handshake 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * client -> server: Stream header 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * client -> server: <auth> message with the OAuth2 token. 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * WAIT_STREAM_HEADER_AFTER_TLS 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * client <- server: Stream header with list of supported authentication 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * methods which is expected to include X-OAUTH2 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * WAIT_AUTH_RESULT 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * client <- server: <success> or <failure> 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * client -> server: Stream header 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * client -> server: <bind> 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * client -> server: <iq><session/></iq> to start the session 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * WAIT_STREAM_HEADER_AFTER_AUTH 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * client <- server: Stream header with list of features that should 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * include <bind>. 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * WAIT_BIND_RESULT 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * client <- server: <bind> result with JID. 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * WAIT_SESSION_IQ_RESULT 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * client <- server: result for <iq><session/></iq> 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * DONE 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @enum {number} 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci */ 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciremoting.XmppLoginHandler.State = { 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci INIT: 0, 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WAIT_STREAM_HEADER: 1, 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WAIT_STARTTLS_RESPONSE: 2, 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci STARTING_TLS: 3, 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WAIT_STREAM_HEADER_AFTER_TLS: 4, 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WAIT_AUTH_RESULT: 5, 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WAIT_STREAM_HEADER_AFTER_AUTH: 6, 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WAIT_BIND_RESULT: 7, 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WAIT_SESSION_IQ_RESULT: 8, 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DONE: 9, 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ERROR: 10 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}; 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciremoting.XmppLoginHandler.prototype.start = function() { 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.state_ = remoting.XmppLoginHandler.State.WAIT_STREAM_HEADER; 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.startStream_('<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>'); 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/** @param {ArrayBuffer} data */ 1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciremoting.XmppLoginHandler.prototype.onDataReceived = function(data) { 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base.debug.assert(this.state_ != remoting.XmppLoginHandler.State.INIT && 1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.state_ != remoting.XmppLoginHandler.State.DONE && 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.state_ != remoting.XmppLoginHandler.State.ERROR); 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.streamParser_.appendData(data); 1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/** 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @param {Element} stanza 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @private 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci */ 1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciremoting.XmppLoginHandler.prototype.onStanza_ = function(stanza) { 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci switch (this.state_) { 1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case remoting.XmppLoginHandler.State.WAIT_STREAM_HEADER: 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (stanza.querySelector('features>starttls')) { 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.state_ = remoting.XmppLoginHandler.State.WAIT_STARTTLS_RESPONSE; 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.onError_(remoting.Error.UNEXPECTED, "Server doesn't support TLS."); 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case remoting.XmppLoginHandler.State.WAIT_STARTTLS_RESPONSE: 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (stanza.localName == "proceed") { 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.state_ = remoting.XmppLoginHandler.State.STARTING_TLS; 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.startTlsCallback_(); 1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.onError_(remoting.Error.UNEXPECTED, 1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "Failed to start TLS: " + 1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (new XMLSerializer().serializeToString(stanza))); 1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case remoting.XmppLoginHandler.State.WAIT_STREAM_HEADER_AFTER_TLS: 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci var mechanisms = Array.prototype.map.call( 1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci stanza.querySelectorAll('features>mechanisms>mechanism'), 1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /** @param {Element} m */ 1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci function(m) { return m.textContent; }); 1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (mechanisms.indexOf("X-OAUTH2")) { 1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.onError_(remoting.Error.UNEXPECTED, 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "OAuth2 is not supported by the server."); 1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.state_ = remoting.XmppLoginHandler.State.WAIT_AUTH_RESULT; 1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case remoting.XmppLoginHandler.State.WAIT_AUTH_RESULT: 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (stanza.localName == 'success') { 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.state_ = 1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci remoting.XmppLoginHandler.State.WAIT_STREAM_HEADER_AFTER_AUTH; 1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.startStream_( 1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci '<iq type="set" id="0">' + 1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci '<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">' + 1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci '<resource>chromoting</resource>'+ 1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci '</bind>' + 1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci '</iq>' + 1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci '<iq type="set" id="1">' + 1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci '<session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>' + 1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci '</iq>'); 1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.onError_(remoting.Error.AUTHENTICATION_FAILED, 1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 'Failed to authenticate: ' + 1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (new XMLSerializer().serializeToString(stanza))); 1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case remoting.XmppLoginHandler.State.WAIT_STREAM_HEADER_AFTER_AUTH: 1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (stanza.querySelector('features>bind')) { 1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.state_ = remoting.XmppLoginHandler.State.WAIT_BIND_RESULT; 1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.onError_(remoting.Error.UNEXPECTED, 1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "Server doesn't support bind after authentication."); 1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case remoting.XmppLoginHandler.State.WAIT_BIND_RESULT: 1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci var jidElement = stanza.querySelector('iq>bind>jid'); 1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (stanza.getAttribute('id') != '0' || 1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci stanza.getAttribute('type') != 'result' || !jidElement) { 2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.onError_(remoting.Error.UNEXPECTED, 2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 'Received unexpected response to bind: ' + 2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (new XMLSerializer().serializeToString(stanza))); 2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.jid_ = jidElement.textContent; 2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.state_ = remoting.XmppLoginHandler.State.WAIT_SESSION_IQ_RESULT; 2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case remoting.XmppLoginHandler.State.WAIT_SESSION_IQ_RESULT: 2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (stanza.getAttribute('id') != '1' || 2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci stanza.getAttribute('type') != 'result') { 2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.onError_(remoting.Error.UNEXPECTED, 2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 'Failed to start session: ' + 2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (new XMLSerializer().serializeToString(stanza))); 2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.state_ = remoting.XmppLoginHandler.State.DONE; 2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.onHandshakeDoneCallback_(this.jid_, this.streamParser_); 2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci default: 2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base.debug.assert(false); 2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciremoting.XmppLoginHandler.prototype.onTlsStarted = function() { 2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base.debug.assert(this.state_ == 2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci remoting.XmppLoginHandler.State.STARTING_TLS); 2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.state_ = remoting.XmppLoginHandler.State.WAIT_STREAM_HEADER_AFTER_TLS; 2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci var cookie = window.btoa("\0" + this.username_ + "\0" + this.authToken_); 2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.startStream_( 2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci '<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" ' + 2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 'mechanism="X-OAUTH2" auth:service="oauth2" ' + 2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 'auth:allow-generated-jid="true" ' + 2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 'auth:client-uses-full-bind-result="true" ' + 2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 'auth:allow-non-google-login="true" ' + 2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 'xmlns:auth="http://www.google.com/talk/protocol/auth">' + 2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cookie + 2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci '</auth>'); 2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}; 2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/** 2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @param {string} text 2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @private 2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci */ 2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciremoting.XmppLoginHandler.prototype.onParserError_ = function(text) { 2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.onError_(remoting.Error.UNEXPECTED, text); 2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/** 2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @param {string} firstMessage Message to send after stream header. 2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @private 2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci */ 2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciremoting.XmppLoginHandler.prototype.startStream_ = function(firstMessage) { 2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.sendMessageCallback_('<stream:stream to="' + this.server_ + 2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci '" version="1.0" xmlns="jabber:client" ' + 2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 'xmlns:stream="http://etherx.jabber.org/streams">' + 2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci firstMessage); 2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.streamParser_ = new remoting.XmppStreamParser(); 2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.streamParser_.setCallbacks(this.onStanza_.bind(this), 2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.onParserError_.bind(this)); 2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/** 2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @param {remoting.Error} error 2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @param {string} text 2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @private 2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci */ 2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciremoting.XmppLoginHandler.prototype.onError_ = function(error, text) { 2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (this.state_ != remoting.XmppLoginHandler.State.ERROR) { 2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.onErrorCallback_(error, text); 2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.state_ = remoting.XmppLoginHandler.State.ERROR; 2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci console.error(text); 2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 279