XMPP Handshake Flow using Gloox C/C++ -
i trying perform xmpp handshake flow mentioned @ https://developers.google.com/cloud-print/docs/rawxmpp.
this allows device subscribe , receive notifications.
as of now, have explored following options:
1) libcurl 2) gloox c/c++ 3) txmpp 4) libjingle
which option choice start with? consider support , maintenance of library major factor.
thanks
following solution using gloox c/c++ library perform xmpp handshake flow:
#include <cassert> #include <iostream> #include <boost/make_shared.hpp> #include <iq.h> #include <parser.h> #include <base64.h> #include <connectiontcpclient.h> #include <connectiontls.h> #include <connectiondatahandler.h> #include <connectionhttpproxy.h> #include <logsink.h> #include <client.h> #include <connectionsocks5proxy.h> using namespace gloox; using namespace std; const string proxyhost = ""; //specify proxy server name const int proxyport = 0; //specify proxy port number const string xmpphost = "talk.google.com"; const int xmppport = 5222; client *c; connectionbase *client_ ; connectiontcpclient* conn0; connectionhttpproxy* conn2; class bot: public connectiondatahandler, taghandler, tlshandler{ public: bot(): parser_(this) { conn0 = new connectiontcpclient(this, log_, proxyhost, proxyport); connectionhttpproxy* conn2 = new connectionhttpproxy( this, conn0, log_, xmpphost, xmppport); client_ = conn0; connectionerror ce = connnoerror; ce = conn2->connect(); assert(ce == connnoerror); conn2->receive(); } virtual void handleconnect(const connectionbase* con) { send("<stream:stream to=\"gmail.com\" xml:lang=\"en\" version=\"1.0\" xmlns:stream=\"http://etherx.jabber.org/streams\" xmlns=\"jabber:client\">\r\n"); } virtual void handlereceiveddata(const connectionbase* con, const string& data) { cerr << "[recv] " << data << endl; string copied = data; int pos = parser_.feed(copied); assert(pos < 0); } virtual void handletag(tag* tag) { if (tag->name() == "stream" && tag->xmlns() == "http://etherx.jabber.org/streams") { sid_ = tag->findattribute("id"); } else{ if (tag->name() == "features") { if (tag->haschild("starttls", "xmlns", "urn:ietf:params:xml:ns:xmpp-tls")) { send(tag("starttls", "xmlns", "urn:ietf:params:xml:ns:xmpp-tls").xml()); } else if (tag->haschild("mechanisms", "xmlns", "urn:ietf:params:xml:ns:xmpp-sasl") && tag->findchild("mechanisms")->haschildwithcdata( "mechanism", "x-oauth2")) { tag a("auth", "xmlns", "urn:ietf:params:xml:ns:xmpp-sasl"); a.addattribute("mechanism", "x-oauth2"); a.addattribute("service", "chromiumsync"); a.addattribute("allow-generated-jid", "true"); a.addattribute("client-uses-full-bind-result", "true"); a.addattribute("auth", "http://www.google.com/talk/protocol/auth"); string credential; credential.append("\0", 1); credential.append(""); //specify bare jid credential.append("\0", 1); credential.append(""); //specify access token a.setcdata(base64::encode64(credential)); send(a.xml()); } else if (tag->haschild("bind", "xmlns", "urn:ietf:params:xml:ns:xmpp-bind")) { tag iq("iq", "xmlns", "jabber:client"); iq.addattribute("type", "set"); iq.addattribute("id", "0"); tag *bind = new tag("bind", "xmlns", "urn:ietf:params:xml:ns:xmpp-bind"); tag *resource = new tag("resource"); resource->setcdata("gcpresource"); bind->addchild(resource); iq.addchild(bind); send(iq.xml()); } } else if (tag->name() == "proceed" && tag->xmlns() == "urn:ietf:params:xml:ns:xmpp-tls") { connectiontls* encryption_client = new connectiontls(this, conn0, log_); encryption_client->registertlshandler(this); client_ = encryption_client; connectionerror ret = encryption_client->connect(); assert(ret == connnoerror); } else if (tag->name() == "success" && tag->xmlns() == "urn:ietf:params:xml:ns:xmpp-sasl") { send("<stream:stream to=\"gmail.com\" xml:lang=\"en\" version=\"1.0\" xmlns:stream=\"http://etherx.jabber.org/streams\" xmlns=\"jabber:client\">\r\n"); } else if (tag->name() == "iq") { if (tag->haschild("bind", "xmlns", "urn:ietf:params:xml:ns:xmpp-bind")) { resource_ = tag->findchild("bind")->findchild("jid")->cdata(); tag iq("iq"); iq.addattribute("type", "set"); iq.addattribute("id", "1"); iq.addchild(new tag("session", "xmlns", "urn:ietf:params:xml:ns:xmpp-session")); send(iq.xml()); //step 2: subscribing notifications if (tag->hasattribute("type", "result")) { tag iq("iq"); iq.addattribute("type", "set"); iq.addattribute("to", ""); //specify bare jid iq.addattribute("id", "3"); tag *bind = new tag("subscribe", "xmlns", "google:push"); tag *resource = new tag("item"); resource->addattribute("channel", "cloudprint.google.com"); resource->addattribute("from", "cloudprint.google.com"); bind->addchild(resource); iq.addchild(bind); send(iq.xml()); } } } } } virtual void handleencrypteddata(const tlsbase* tls, const string& data) { cout << "handleencrypteddata" << endl; } virtual void handledecrypteddata(const tlsbase* tls, const string& data) { cout << "handledecrypteddata" << endl; } virtual void handlehandshakeresult(const tlsbase* tls, bool, certinfo& cert) { cout << "handlehandshakeresult" << endl; } virtual void handledisconnect(const connectionbase* con, connectionerror) { cout << "handledisconnect" << endl; } private: logsink log_; string sid_; string resource_; parser parser_; connectionbase *client_; void send(const string &data) { cerr << "[send] " << data << endl; client_->send(data); } }; int main() { bot bot; }
Comments
Post a Comment