void Registration::stanzaRequestResult(const Jid &AStreamJid, const Stanza &AStanza) { XmppStanzaError err = AStanza.type()!="result" ? XmppStanzaError(AStanza) : XmppStanzaError::null; if (FSendRequests.contains(AStanza.id())) { QDomElement queryElem = AStanza.firstElement("query",NS_JABBER_REGISTER); IRegisterFields fields = readFields(AStanza.from(),queryElem); if (AStanza.type()=="result" || (fields.fieldMask & IRegisterFields::Form)>0) { LOG_STRM_INFO(AStreamJid,QString("Registration fields loaded, from=%1, id=%2").arg(AStanza.from(),AStanza.id())); emit registerFields(AStanza.id(),fields); } else { LOG_STRM_WARNING(AStreamJid,QString("Failed to load registration fields from=%1, id=%2: %3").arg(AStanza.from(),AStanza.id(),err.condition())); emit registerError(AStanza.id(),err); } FSendRequests.removeAll(AStanza.id()); } else if (FSubmitRequests.contains(AStanza.id())) { if (AStanza.type()=="result") { LOG_STRM_INFO(AStreamJid,QString("Registration submit accepted, from=%1, id=%2").arg(AStanza.from(),AStanza.id())); emit registerSuccess(AStanza.id()); } else { LOG_STRM_WARNING(AStreamJid,QString("Registration submit rejected, from=%1, id=%2: %3").arg(AStanza.from(),AStanza.id(),err.condition())); emit registerError(AStanza.id(),err); } FSubmitRequests.removeAll(AStanza.id()); } }
void Roster::stanzaRequestResult(const Jid &AStreamJid, const Stanza &AStanza) { if (AStanza.id() == FDelimRequestId) { FDelimRequestId.clear(); QString groupDelim = ROSTER_GROUP_DELIMITER; if (AStanza.type() == "result") { groupDelim = AStanza.firstElement("query",NS_JABBER_PRIVATE).firstChildElement("roster").text(); if (groupDelim.isEmpty()) { groupDelim = ROSTER_GROUP_DELIMITER; LOG_STRM_INFO(streamJid(),QString("Saving default roster group delimiter on server, delimiter='%1'").arg(groupDelim)); Stanza delim("iq"); delim.setType("set").setId(FStanzaProcessor->newId()); QDomElement elem = delim.addElement("query",NS_JABBER_PRIVATE); elem.appendChild(delim.createElement("roster",NS_STORAGE_GROUP_DELIMITER)).appendChild(delim.createTextNode(groupDelim)); FStanzaProcessor->sendStanzaOut(AStreamJid,delim); } else { LOG_STRM_INFO(streamJid(),QString("Roster group delimiter loaded, delimiter='%1'").arg(groupDelim)); } } else { LOG_STRM_WARNING(streamJid(),QString("Failed to load roster group delimiter: %1").arg(XmppStanzaError(AStanza).condition())); } setGroupDelimiter(groupDelim); requestRosterItems(); } else if (AStanza.id() == FOpenRequestId) { FOpenRequestId.clear(); if (AStanza.type() == "result") { LOG_STRM_INFO(streamJid(),"Roster items loaded"); processItemsElement(AStanza.firstElement("query",NS_JABBER_ROSTER),true); FOpened = true; emit opened(); } else { LOG_STRM_WARNING(streamJid(),QString("Failed to load roster items: %1").arg(XmppStanzaError(AStanza).condition())); FXmppStream->abort(XmppError(IERR_ROSTER_REQUEST_FAILED)); } } }
void InBandStream::stanzaRequestResult(const Jid &AStreamJid, const Stanza &AStanza) { Q_UNUSED(AStreamJid); if (AStanza.id() == FDataIqRequestId) { if (AStanza.isResult()) { FDataIqRequestId.clear(); sendNextPaket(); } else { abort(XmppStanzaError(AStanza)); } } else if (AStanza.id() == FOpenRequestId) { if (AStanza.isResult()) { FSHIData = insertStanzaHandle(FStanzaType==StanzaMessage ? SHC_INBAND_DATA_MESSAGE : SHC_INBAND_DATA_IQ); FSHIClose = insertStanzaHandle(SHC_INBAND_CLOSE); if (FSHIData>0 && FSHIClose>0) setStreamState(IDataStreamSocket::Opened); else abort(XmppError(IERR_INBAND_STREAM_NOT_OPENED)); } else { abort(XmppStanzaError(AStanza)); } } else if (AStanza.id() == FCloseRequestId) { setStreamState(IDataStreamSocket::Closed); } }
bool InBandStream::stanzaReadWrite(int AHandleId, const Jid &AStreamJid, Stanza &AStanza, bool &AAccept) { QDomElement elem = AStanza.firstElement(QString::null,NS_INBAND_BYTESTREAMS); if (AHandleId==FSHIData && elem.attribute("sid")==FStreamId) { AAccept = true; if (AStanza.firstElement("error").isNull()) { QByteArray data = QByteArray::fromBase64(elem.text().toLatin1()); if (FSeqIn==elem.attribute("seq").toInt() && data.size()>0 && data.size()<=FBlockSize) { if (AStanza.kind() == STANZA_KIND_IQ) { Stanza result = FStanzaProcessor->makeReplyResult(AStanza); FStanzaProcessor->sendStanzaOut(AStreamJid,result); } FThreadLock.lockForWrite(); FReadBuffer.write(data); FThreadLock.unlock(); FSeqIn = FSeqIn<USHRT_MAX ? FSeqIn+1 : 0; emit readyRead(); FReadyReadCondition.wakeAll(); } else { abort(XmppError(IERR_INBAND_STREAM_INVALID_DATA)); } } else { abort(XmppStanzaError(AStanza)); } } else if (AHandleId==FSHIOpen && elem.attribute("sid")==FStreamId) { AAccept = true; removeStanzaHandle(FSHIOpen); if (FStreamState == IDataStreamSocket::Opening) { QDomElement openElem = AStanza.firstElement("open"); FBlockSize = openElem.attribute("block-size").toInt(); if (FBlockSize>MINIMUM_BLOCK_SIZE && FBlockSize<=FMaxBlockSize) { FStanzaType = openElem.attribute("stanza")==STANZA_KIND_MESSAGE ? StanzaMessage : StanzaIq; FSHIData = insertStanzaHandle(FStanzaType==StanzaMessage ? SHC_INBAND_DATA_MESSAGE : SHC_INBAND_DATA_IQ); FSHIClose = insertStanzaHandle(SHC_INBAND_CLOSE); if (FSHIData>0 && FSHIClose>0) { Stanza result = FStanzaProcessor->makeReplyResult(AStanza); if (FStanzaProcessor->sendStanzaOut(AStreamJid,result)) setStreamState(IDataStreamSocket::Opened); else abort(XmppError(IERR_INBAND_STREAM_NOT_OPENED)); } else { Stanza error = FStanzaProcessor->makeReplyError(AStanza,XmppStanzaError::EC_INTERNAL_SERVER_ERROR); FStanzaProcessor->sendStanzaOut(AStreamJid,error); abort(XmppError(IERR_INBAND_STREAM_NOT_OPENED)); } } else { Stanza error = FStanzaProcessor->makeReplyError(AStanza,XmppStanzaError::EC_RESOURCE_CONSTRAINT); FStanzaProcessor->sendStanzaOut(AStreamJid,error); abort(XmppError(IERR_INBAND_STREAM_INVALID_BLOCK_SIZE)); } } else { LOG_STRM_WARNING(AStreamJid,QString("Unexpected open request from=%1, sid=%2: Invalid state").arg(AStanza.from(),FStreamId)); Stanza error = FStanzaProcessor->makeReplyError(AStanza,XmppStanzaError::EC_UNEXPECTED_REQUEST); FStanzaProcessor->sendStanzaOut(AStreamJid,error); } } else if (AHandleId==FSHIClose && elem.attribute("sid")==FStreamId) { AAccept = true; Stanza result = FStanzaProcessor->makeReplyResult(AStanza); FStanzaProcessor->sendStanzaOut(AStreamJid,result); setStreamState(IDataStreamSocket::Closed); } return false; }
void PrivateStorage::stanzaRequestResult(const Jid &AStreamJid, const Stanza &AStanza) { if (FSaveRequests.contains(AStanza.id())) { QDomElement dataElem = FSaveRequests.take(AStanza.id()); if (AStanza.isResult()) { LOG_STRM_INFO(AStreamJid,QString("Private data saved on server, ns=%1, id=%2").arg(dataElem.namespaceURI(),AStanza.id())); notifyDataChanged(AStreamJid,dataElem.tagName(),dataElem.namespaceURI()); } else { LOG_STRM_WARNING(AStreamJid,QString("Private data saved in local storage, ns=%1, id=%2: %3").arg(dataElem.namespaceURI(),AStanza.id(),XmppStanzaError(AStanza).condition())); } saveOptionsElement(AStreamJid,dataElem); emit dataSaved(AStanza.id(),AStreamJid,dataElem); } else if (FLoadRequests.contains(AStanza.id())) { QDomElement dataElem; QDomElement loadElem = FLoadRequests.take(AStanza.id()); if (AStanza.isResult()) { dataElem = AStanza.firstElement("query",NS_JABBER_PRIVATE).firstChildElement(loadElem.tagName()); LOG_STRM_INFO(AStreamJid,QString("Private data loaded from server, ns=%1, id=%2").arg(loadElem.namespaceURI(),AStanza.id())); } else { LOG_STRM_WARNING(AStreamJid,QString("Private data loaded from local storage, ns=%1, id=%2: %3").arg(loadElem.namespaceURI(),AStanza.id(),XmppStanzaError(AStanza).condition())); } if (dataElem.isNull()) dataElem = loadOptionsElement(AStreamJid,loadElem.tagName(),loadElem.namespaceURI()); emit dataLoaded(AStanza.id(),AStreamJid,insertElement(AStreamJid,dataElem)); } else if (FRemoveRequests.contains(AStanza.id())) { QDomElement dataElem = FRemoveRequests.take(AStanza.id()); if (AStanza.isResult()) { LOG_STRM_INFO(AStreamJid,QString("Private data removed from server, ns=%1, id=%2").arg(dataElem.namespaceURI(),AStanza.id())); notifyDataChanged(AStreamJid,dataElem.tagName(),dataElem.namespaceURI()); } else { LOG_STRM_WARNING(AStreamJid,QString("Private data removed from local storage, ns=%1, id=%2: %3").arg(dataElem.namespaceURI(),AStanza.id(),XmppStanzaError(AStanza).condition())); } removeElement(AStreamJid,dataElem.tagName(),dataElem.namespaceURI()); removeOptionsElement(AStreamJid,dataElem.tagName(),dataElem.namespaceURI()); emit dataRemoved(AStanza.id(),AStreamJid,dataElem); } }
void ClientInfo::stanzaRequestResult(const Jid &AStreamJid, const Stanza &AStanza) { Q_UNUSED(AStreamJid); if (FSoftwareId.contains(AStanza.id())) { Jid contactJid = FSoftwareId.take(AStanza.id()); SoftwareItem &software = FSoftwareItems[contactJid]; if (AStanza.isResult()) { QDomElement query = AStanza.firstElement("query"); software.name = query.firstChildElement("name").text(); software.version = query.firstChildElement("version").text(); software.os = query.firstChildElement("os").text(); software.status = SoftwareLoaded; LOG_STRM_INFO(AStreamJid,QString("Received software version from=%1").arg(AStanza.from())); } else { software.name = XmppStanzaError(AStanza).errorMessage(); software.version.clear(); software.os.clear(); software.status = SoftwareError; LOG_STRM_WARNING(AStreamJid,QString("Failed to request software version from=%1: %2").arg(AStanza.from(),software.name)); } emit softwareInfoChanged(contactJid); } else if (FActivityId.contains(AStanza.id())) { Jid contactJid = FActivityId.take(AStanza.id()); ActivityItem &activity = FActivityItems[contactJid]; if (AStanza.isResult()) { QDomElement query = AStanza.firstElement("query"); activity.dateTime = QDateTime::currentDateTime().addSecs(0-query.attribute("seconds","0").toInt()); activity.text = query.text(); LOG_STRM_INFO(AStreamJid,QString("Received last activity from=%1").arg(AStanza.from())); } else { activity.dateTime = QDateTime(); activity.text = XmppStanzaError(AStanza).errorMessage(); LOG_STRM_WARNING(AStreamJid,QString("Failed to request last activity from=%1: %2").arg(AStanza.from(),activity.text)); } emit lastActivityChanged(contactJid); } else if (FTimeId.contains(AStanza.id())) { Jid contactJid = FTimeId.take(AStanza.id()); QDomElement time = AStanza.firstElement("time"); QString tzo = time.firstChildElement("tzo").text(); QString utc = time.firstChildElement("utc").text(); if (AStanza.isResult() && !tzo.isEmpty() && !utc.isEmpty()) { TimeItem &tItem = FTimeItems[contactJid]; tItem.zone = DateTime::tzdFromX85(tzo); tItem.delta = QDateTime::currentDateTime().secsTo(DateTime(utc).toLocal()); tItem.ping = tItem.ping - QTime::currentTime().msecsTo(QTime(0,0,0,0)); LOG_STRM_INFO(AStreamJid,QString("Received current time from=%1").arg(AStanza.from())); } else { FTimeItems.remove(contactJid); LOG_STRM_WARNING(AStreamJid,QString("Failed to request current time from=%1: %2").arg(AStanza.from(),XmppStanzaError(AStanza).condition())); } emit entityTimeChanged(contactJid); } }
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; }