Cloud Print

XMPP Handshake Flow

If you are not using jiblingle library and are instead building the XMPP handshake yourself, use this documentation to understand what the typical stanzas used in the GCP XMPP handshake flow are. The XMPP Standards Foundation lists more information on the protocol and on XML schemas here.

Step #1: Authentication

**** TLS Negotiation Handshake Begin (see the “Use of TLS” section under http://xmpp.org/rfcs/rfc3920.html) ****


a) Outgoing stanza from GCP proxy or printer

<stream:stream to="gmail.com" xml:lang="en" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client">

b) Incoming stanza from Google Talk server

<stream:stream from="gmail.com" id="{ID}" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client">
<stream:features>
  <starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"><required/></starttls>
  <mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
    <mechanism>X-GOOGLE-TOKEN</mechanism><mechanism>X-OAUTH2</mechanism>
  </mechanisms>
</stream:features>

c) Outgoing stanza from Google Cloud Print proxy or printer

<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>

d) Incoming stanza from Google Talk server

<proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>

**** TLS Negotiation Handshake End ****

**** SASL Authentication Handshake Begin (see the “Use of SASL” section under http://xmpp.org/rfcs/rfc3920.html) ****


e) Outgoing stanza from Google Cloud Print proxy or printer

<stream:stream to="gmail.com" xml:lang="en" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client">

f) Incoming stanza from Google Talk server

<stream:stream from="gmail.com" id="{ID}" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client">

g) Incoming stanza from Google Talk server

<stream:features>
  <mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
    <mechanism>PLAIN</mechanism>
    <mechanism>X-GOOGLE-TOKEN</mechanism>
    <mechanism>X-OAUTH2</mechanism>
  </mechanisms>
</stream:features>

This incoming stanza specifies that the Google Talk server supports the PLAIN, X-GOOGLE-TOKEN as well as the X-OAUTH2 authentication mechanisms. Since we are using an OAuth2 token, we will choose the X-OAUTH2 mechanism in our reply.

h) Outgoing stanza from Google Cloud Print proxy or printer

<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="X-OAUTH2" auth:service="chromiumsync" auth:allow-generated-jid="true" auth:client-uses-full-bind-result="true" xmlns:auth="http://www.google.com/talk/protocol/auth">
  {Base-64 encoded authentication data}
</auth>

Refer to the StartSaslAuth method in talk/xmpp/saslcookiemechanism.h under the libjingle sources at http://code.google.com/p/libjingle/source/checkout for information on how to encode the authentication data. The following is a sample of what this data may look like:

std::string credential;
credential.append("\0", 1);
credential.append(username_);
credential.append("\0", 1);
credential.append(cookie_);
el->AddText(Base64Encode(credential));

Here, cookie_ is an OAuth2 access token which you obtained from the anonymous registration flow.

i) Incoming stanza from Google Talk server

<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>

**** SASL Authentication Handshake End ****


j) Outgoing stanza from Google Cloud Print proxy or printer

<stream:stream to="gmail.com" xml:lang="en" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client">

k) Incoming stanza from Google Talk server

<stream:stream from="gmail.com" id="{ID}" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client">
<stream:features>
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/>
<session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>
</stream:features>

l) Outgoing stanza from Google Cloud Print proxy or printer

<iq type="set" id="0">
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
    <resource>{A short resouce name - maybe the printer name}</resource>
  </bind>
</iq>

m) Incoming stanza from Google Talk server

<iq id="0" type="result">
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
    <jid>{Full JID}</jid>
  </bind>
</iq>

Note: The proxy/printer should extract the Bare JID from the above returned Full JID and use that exactly in subsequent requests that take in a Bare JID. The case should be preserved.

n) Outgoing stanza from Google Cloud Print proxy or printer

<iq type="set" id="1"><session xmlns="urn:ietf:params:xml:ns:xmpp-session"/></iq>

o) Incoming stanza from Google Talk server

<iq type="result" id="1"/>

Step #2: Subscribing for notifications

**** Google Cloud Print subscription handshake begin ****


p) Outgoing stanza from Google Cloud Print proxy or printer

<iq type="set" to="{Bare JID}" id="3">
  <subscribe xmlns="google:push">
    <item channel="cloudprint.google.com" from="cloudprint.google.com"/>
  </subscribe>
</iq>

q) Incoming stanza from Google Talk server

<iq to="{Full JID}" from="{Bare JID}" id="3" type="result"/>

**** Google Cloud Print subscription handshake end ****

Step #3: Receiving notifications

When the user submits a print job to the printer, the Cloud Print service pushes a notification to subscribers. The notification looks like this:

<message from="cloudprint.google.com" to=”{Full JID}”>
  <push:push channel="cloudprint.google.com" xmlns:push="google:push">
    <push:recipient to="{Bare JID}"></push:recipient>
    <push:data>{Base-64 encoded printer id}</push:data>
  </push:push>
</message>

Authentication required

You need to be signed in with Google+ to do that.

Signing you in...

Google Developers needs your permission to do that.