bool StartTLSFeature::start(const QDomElement &AElem) { if (AElem.tagName() == "starttls") { if (FXmppStream->connection()->isEncryptionSupported() && !FXmppStream->connection()->isEncrypted()) { Stanza request("starttls"); request.setAttribute("xmlns",NS_FEATURE_STARTTLS); FXmppStream->insertXmppStanzaHandler(XSHO_XMPP_FEATURE,this); FXmppStream->sendStanza(request); LOG_STRM_INFO(FXmppStream->streamJid(),"StartTLS negotiation request sent"); return true; } else if (!FXmppStream->connection()->isEncryptionSupported()) { LOG_STRM_WARNING(FXmppStream->streamJid(),"Failed to send StartTLS negotiation request: Encryption is not supported"); } } else { LOG_STRM_ERROR(FXmppStream->streamJid(),QString("Failed to send StartTLS negotiation request: Invalid element=%1").arg(AElem.tagName())); } deleteLater(); return false; }
bool StartTLSFeature::xmppStanzaIn(IXmppStream *AXmppStream, Stanza &AStanza, int AOrder) { if (AXmppStream==FXmppStream && AOrder==XSHO_XMPP_FEATURE) { FXmppStream->removeXmppStanzaHandler(XSHO_XMPP_FEATURE,this); if (AStanza.tagName() == "proceed") { if (FXmppStream->connection()->startEncryption()) { LOG_STRM_INFO(FXmppStream->streamJid(),"Starting StartTLS encryption"); connect(FXmppStream->connection()->instance(),SIGNAL(encrypted()),SLOT(onConnectionEncrypted())); } else { LOG_STRM_ERROR(FXmppStream->streamJid(),"Failed to negotiate StartTLS encryption: Handshake not started"); emit error(XmppError(IERR_STARTTLS_NOT_STARTED)); } } else if (AStanza.tagName() == "failure") { LOG_STRM_WARNING(FXmppStream->streamJid(),"Failed to negotiate StartTLS encryption: Negotiation failed"); emit error(XmppError(IERR_STARTTLS_NEGOTIATION_FAILED)); } else { LOG_STRM_WARNING(FXmppStream->streamJid(),"Failed to negotiate StartTLS encryption: Invalid responce"); emit error(XmppError(IERR_STARTTLS_INVALID_RESPONCE)); } return true; } return false; }
bool MultiUserChat::setAffiliation(const QString &ANick, const QString &AAffiliation, const QString &AReason) { if (FStanzaProcessor && isOpen()) { IMultiUser *user = userByNick(ANick); if (user) { Stanza request("iq"); request.setTo(FRoomJid.bare()).setType("set").setId(FStanzaProcessor->newId()); QDomElement itemElem = request.addElement("query",NS_MUC_ADMIN).appendChild(request.createElement("item")).toElement(); itemElem.setAttribute("affiliation",AAffiliation); itemElem.setAttribute("nick",ANick); if (!user->data(MUDR_REAL_JID).toString().isEmpty()) itemElem.setAttribute("jid",user->data(MUDR_REAL_JID).toString()); if (!AReason.isEmpty()) itemElem.appendChild(request.createElement("reason")).appendChild(request.createTextNode(AReason)); if (FStanzaProcessor->sendStanzaRequest(this,FStreamJid,request,0)) { LOG_STRM_INFO(FStreamJid,QString("User affiliation change request sent, room=%1, user=%2, affiliation=%3").arg(FRoomJid.bare(),ANick,AAffiliation)); return true; } else { LOG_STRM_WARNING(FStreamJid,QString("Failed to send user affiliation change request, room=%1, user=%1, affiliation=%3").arg(FRoomJid.bare(),ANick,AAffiliation)); } } else { LOG_STRM_ERROR(FStreamJid,QString("Failed to change user affiliation, room=%1, user=%2: User not found").arg(FRoomJid.bare(),ANick)); } } return false; }
bool CompressFeature::start(const QDomElement &AElem) { if (AElem.tagName() == "compression") { QDomElement elem = AElem.firstChildElement("method"); while (!elem.isNull()) { if (elem.text() == "zlib") { if (startZlib()) { LOG_STRM_INFO(FXmppStream->streamJid(),QString("Starting stream compression with ZLib=%1").arg(ZLIB_VERSION)); Stanza compress("compress"); compress.setAttribute("xmlns",NS_PROTOCOL_COMPRESS); compress.addElement("method").appendChild(compress.createTextNode("zlib")); FXmppStream->insertXmppStanzaHandler(XSHO_XMPP_FEATURE,this); FXmppStream->sendStanza(compress); return true; } else { LOG_STRM_ERROR(FXmppStream->streamJid(),"Failed to initialize ZLib"); } break; } elem = elem.nextSiblingElement("method"); } if (elem.isNull()) LOG_STRM_WARNING(FXmppStream->streamJid(),"Failed to start stream compression: Method not supported"); } else { LOG_STRM_ERROR(FXmppStream->streamJid(),QString("Failed to start stream compression: Invalid element name %1").arg(AElem.tagName())); } deleteLater(); return false; }
bool SASLAuthFeature::start(const QDomElement &AElem) { if (AElem.tagName() == "mechanisms") { if (!xmppStream()->isEncryptionRequired() || xmppStream()->connection()->isEncrypted()) { QStringList mechanisms; QDomElement mechElem = AElem.firstChildElement("mechanism"); while (!mechElem.isNull()) { QString mech = mechElem.text().toUpper(); if (SupportedMechanisms.contains(mech)) mechanisms.append(mech); mechElem = mechElem.nextSiblingElement("mechanism"); } if (!mechanisms.isEmpty()) { if (!FXmppStream->requestPassword()) sendAuthRequest(mechanisms); else FMechanisms = mechanisms; return true; } else { LOG_STRM_WARNING(FXmppStream->streamJid(),QString("Failed to send authorization request: Supported mechanism not found")); } } else { XmppError err(IERR_XMPPSTREAM_NOT_SECURE); LOG_STRM_WARNING(FXmppStream->streamJid(),QString("Failed to send authorization request: %1").arg(err.condition())); emit error(err); } } else { LOG_STRM_ERROR(FXmppStream->streamJid(),QString("Failed to send authorization request: Invalid element=%1").arg(AElem.tagName())); } deleteLater(); return false; }
bool IqAuthFeature::xmppStanzaIn(IXmppStream *AXmppStream, Stanza &AStanza, int AOrder) { if (AXmppStream==FXmppStream && AOrder==XSHO_XMPP_FEATURE) { if (AStanza.id() == "getIqAuth") { if (AStanza.type() == "result") { Stanza auth("iq"); auth.setType("set").setTo(FXmppStream->streamJid().domain()).setId("setIqAuth"); QDomElement query = auth.addElement("query",NS_JABBER_IQ_AUTH); query.appendChild(auth.createElement("username")).appendChild(auth.createTextNode(FXmppStream->streamJid().pNode())); query.appendChild(auth.createElement("resource")).appendChild(auth.createTextNode(FXmppStream->streamJid().resource())); QDomElement reqElem = AStanza.firstElement("query",NS_JABBER_IQ_AUTH); if (!reqElem.firstChildElement("digest").isNull()) { QByteArray shaData = FXmppStream->streamId().toUtf8()+FXmppStream->password().toUtf8(); QByteArray shaDigest = QCryptographicHash::hash(shaData,QCryptographicHash::Sha1).toHex(); query.appendChild(auth.createElement("digest")).appendChild(auth.createTextNode(shaDigest.toLower().trimmed())); FXmppStream->sendStanza(auth); LOG_STRM_INFO(AXmppStream->streamJid(),"Username and encrypted password sent"); } else if (!reqElem.firstChildElement("password").isNull()) { if (FXmppStream->connection()->isEncrypted()) { query.appendChild(auth.createElement("password")).appendChild(auth.createTextNode(FXmppStream->password())); FXmppStream->sendStanza(auth); LOG_STRM_INFO(AXmppStream->streamJid(),"Username and plain text password sent"); } else { LOG_STRM_ERROR(AXmppStream->streamJid(),"Failed to send username and plain text password: Connection not encrypted"); emit error(XmppError(IERR_XMPPSTREAM_NOT_SECURE)); } } } else { XmppStanzaError err(AStanza); LOG_STRM_ERROR(AXmppStream->streamJid(),QString("Failed to receive authentication initialization: %1").arg(err.condition())); emit error(err); } return true; } else if (AStanza.id() == "setIqAuth") { FXmppStream->removeXmppStanzaHandler(XSHO_XMPP_FEATURE,this); if (AStanza.type() == "result") { LOG_STRM_INFO(AXmppStream->streamJid(),"Username and password accepted"); deleteLater(); emit finished(false); } else { XmppStanzaError err(AStanza); LOG_STRM_WARNING(AXmppStream->streamJid(),QString("Username and password rejected: %1").arg(err.condition())); emit error(XmppStanzaError(AStanza)); } return true; } } return false; }