#include "JabberStream.h" #include "EntityCaps.h" #include #include #include #include "crypto/SHA1.h" #include "config.h" extern std::string appVersion; extern std::string appName; std::string EntityCaps::capsHash=""; ProcessResult EntityCaps::blockArrived(JabberDataBlockRef block, const ResourceContextRef rc) { JabberDataBlockRef query=block->getChildByName("query"); if (!query) return BLOCK_REJECTED; std::string xmlns=query->getAttribute("xmlns"); if (xmlns!="http://jabber.org/protocol/disco#info") return BLOCK_REJECTED; std::string node=query->getAttribute("node"); if (node.length()>0) if (node.find("http://bombus-im.org/ng")<0) return BLOCK_REJECTED; JabberDataBlock result ("iq"); result.setAttribute("to", block->getAttribute("from")); result.setAttribute("type", "result"); result.setAttribute("id", block->getAttribute("id")); result.addChild(query); JabberDataBlockRef identity=query->addChild("identity",NULL); identity->setAttribute("category", rc->myCaps->identityCategory.c_str()); identity->setAttribute("type", rc->myCaps->identityType.c_str()); identity->setAttribute("name", rc->myCaps->identityName.c_str()); rc->myCaps->appendFeatures(query); rc->jabberStream->sendStanza(result); return BLOCK_PROCESSED; } JabberDataBlockRef ClientCaps::presenceEntityCaps() { JabberDataBlockRef c=JabberDataBlockRef(new JabberDataBlock("c")); c->setAttribute("xmlns", "http://jabber.org/protocol/caps"); c->setAttribute("node", node); c->setAttribute("ver", getCapsHash()); c->setAttribute("hash", alg); //c->setAttribute("ver", appVersion.c_str()); //c->setAttribute("ext", appVersion.c_str()); return c; } void ClientCaps::appendFeatures( JabberDataBlockRef result ) const { for (size_t i=0; iaddChild("feature", NULL)->setAttribute("var", features[i]); } } typedef boost::shared_ptr MDRef; const std::string & ClientCaps::getCapsHash() { if (capsHash.length()) return capsHash; //sorting std::stable_sort(features.begin(), features.end(), std::less() ); MDRef hashAlg=MDRef(new SHA1()); hashAlg->init(); hashAlg->updateASCII(identityCategory.c_str()); hashAlg->updateASCII("/"); hashAlg->updateASCII(identityType.c_str()); hashAlg->updateASCII("//"); hashAlg->updateASCII(identityName.c_str()); hashAlg->updateASCII("<"); for (size_t i=0; iupdateASCII(features[i]); hashAlg->updateASCII("<"); } hashAlg->finish(); capsHash=hashAlg->getDigestBase64(); return capsHash; } void ClientCaps::addFeature( const std::string feature ) { for (size_t i=0; idelivered) addFeature("urn:xmpp:receipts"); //xep-0184 if (Config::getInstance()->composing) addFeature("http://jabber.org/protocol/chatstates"); //addFeature("jabber:x:event"); // xep-0022; deprecated addFeature("urn:xmpp:ping"); // xep-0199 addFeature("urn:xmpp:time"); }