bool Roster::stanzaReadWrite(int AHandlerId, const Jid &AStreamJid, Stanza &AStanza, bool &AAccept) { if (AHandlerId == FSHIRosterPush) { if (isOpen() && AStanza.isFromServer()) { AAccept = true; LOG_STRM_DEBUG(streamJid(),"Roster items push received"); processItemsElement(AStanza.firstElement("query",NS_JABBER_ROSTER),false); Stanza result = FStanzaProcessor->makeReplyResult(AStanza); FStanzaProcessor->sendStanzaOut(AStreamJid,result); } else if (!isOpen()) { REPORT_ERROR("Failed to process roster items push: Roster is closed"); } else if (!AStanza.isFromServer()) { REPORT_ERROR("Failed to process roster items push: Invalid stanza sender"); } } else if (AHandlerId == FSHISubscription) { Jid contactJid = AStanza.from(); QString status = AStanza.firstElement("status").text(); if (AStanza.type() == SUBSCRIPTION_SUBSCRIBE) { AAccept = true; FSubscriptionRequests += contactJid.bare(); LOG_STRM_INFO(streamJid(),QString("Subscribe presence received from=%1, status=%2").arg(contactJid.full(),status)); emit subscriptionReceived(AStanza.from(),IRoster::Subscribe,status); } else if (AStanza.type() == SUBSCRIPTION_SUBSCRIBED) { AAccept = true; LOG_STRM_INFO(streamJid(),QString("Subscribed presence received from=%1, status=%2").arg(contactJid.full(),status)); emit subscriptionReceived(AStanza.from(),IRoster::Subscribed,status); } else if (AStanza.type() == SUBSCRIPTION_UNSUBSCRIBE) { AAccept = true; FSubscriptionRequests -= contactJid.bare(); LOG_STRM_INFO(streamJid(),QString("Unsubscribe presence received from=%1, status=%2").arg(contactJid.full(),status)); emit subscriptionReceived(AStanza.from(),IRoster::Unsubscribe,status); } else if (AStanza.type() == SUBSCRIPTION_UNSUBSCRIBED) { AAccept = true; LOG_STRM_INFO(streamJid(),QString("Unsubscribed presence received from=%1, status=%2").arg(contactJid.full(),status)); emit subscriptionReceived(AStanza.from(),IRoster::Unsubscribed,status); } } return false; }
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)); } } }
bool RosterItemExchange::stanzaReadWrite(int AHandleId, const Jid &AStreamJid, Stanza &AStanza, bool &AAccept) { if (FSHIExchangeRequest==AHandleId && !AStanza.isError()) { QDomElement xElem = AStanza.firstElement("x",NS_ROSTERX); if (!xElem.isNull() && !xElem.firstChildElement("item").isNull()) { AAccept = true; LOG_STRM_INFO(AStreamJid,QString("Roster exchange request received, from=%1, kind=%2, id=%3").arg(AStanza.from(),AStanza.kind(),AStanza.id())); IRosterExchangeRequest request; request.streamJid = AStreamJid; request.contactJid = AStanza.from(); request.id = AStanza.kind()==STANZA_KIND_IQ ? AStanza.id() : QString::null; request.message = AStanza.kind()==STANZA_KIND_MESSAGE ? Message(AStanza).body() : QString::null; QList<Jid> existItems; QDomElement itemElem = xElem.firstChildElement("item"); bool isItemsValid = true; while (isItemsValid && !itemElem.isNull()) { IRosterExchangeItem item; item.itemJid = Jid(itemElem.attribute("jid")).bare(); item.name = itemElem.attribute("name"); item.action = itemElem.attribute("action",ROSTEREXCHANGE_ACTION_ADD); QDomElement groupElem = itemElem.firstChildElement("group"); while(!groupElem.isNull()) { item.groups += groupElem.text(); groupElem = groupElem.nextSiblingElement("group"); } if (item.itemJid.isValid() && !existItems.contains(item.itemJid) && (item.action==ROSTEREXCHANGE_ACTION_ADD || item.action==ROSTEREXCHANGE_ACTION_DELETE || item.action==ROSTEREXCHANGE_ACTION_MODIFY)) { request.items.append(item); existItems.append(item.itemJid); } else { isItemsValid = false; LOG_STRM_WARNING(AStreamJid,QString("Failed to append roster exchange item, jid=%1, action=%2: Invalid item").arg(item.itemJid.bare(),item.action)); } itemElem = itemElem.nextSiblingElement("item"); } if (isItemsValid && !request.items.isEmpty()) processRequest(request); else replyRequestError(request,XmppStanzaError::EC_BAD_REQUEST); return true; } } return false; }
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()); } }
bool SASLBind::xmppStanzaIn(IXmppStream *AXmppStream, Stanza &AStanza, int AOrder) { if (AXmppStream==FXmppStream && AOrder==XSHO_XMPP_FEATURE && AStanza.id()=="bind") { FXmppStream->removeXmppStanzaHandler(this, XSHO_XMPP_FEATURE); if (AStanza.type() == "result") { Jid streamJid = AStanza.firstElement().firstChild().toElement().text(); if (streamJid.isValid()) { LogDetaile(QString("[SASLBind][%1] XMPP session binded with resource='%2'").arg(FXmppStream->streamJid().bare()).arg(streamJid.resource())); deleteLater(); FXmppStream->setStreamJid(streamJid); emit finished(false); } else { LogError(QString("[SASLBind][%1] Invalid XMPP stream JID in response").arg(FXmppStream->streamJid().bare())); emit error(tr("Invalid XMPP stream JID in SASL bind response")); } } else { ErrorHandler err(AStanza.element()); LogError(QString("[SASLBind] Failed to bind XMPP session: %1").arg(err.message())); emit error(err.message()); } return true; } return false; }
bool Roster::xmppStanzaIn(IXmppStream *AXmppStream, Stanza &AStanza, int AOrder) { if (!FVerSupported && !isOpen() && FXmppStream==AXmppStream && AOrder==XSHO_XMPP_FEATURE) { if (AStanza.element().nodeName()=="stream:features" && !AStanza.firstElement("ver",NS_FEATURE_ROSTER_VER).isNull()) { FVerSupported = true; LOG_STRM_INFO(streamJid(),"Roster versioning is supported by server"); } } 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 Gateways::stanzaRequestResult(const Jid &AStreamJid, const Stanza &AStanza) { Q_UNUSED(AStreamJid); if (FPromptRequests.contains(AStanza.id())) { if (AStanza.type() == "result") { LOG_STRM_DEBUG(AStreamJid,QString("Legacy user prompt received, id=%1").arg(AStanza.id())); QString desc = AStanza.firstElement("query",NS_JABBER_GATEWAY).firstChildElement("desc").text(); QString prompt = AStanza.firstElement("query",NS_JABBER_GATEWAY).firstChildElement("prompt").text(); emit promptReceived(AStanza.id(),desc,prompt); } else { XmppStanzaError err(AStanza); LOG_STRM_WARNING(AStreamJid,QString("Failed to receive legacy user prompt, id=%1: %2").arg(AStanza.id(),err.condition())); emit errorReceived(AStanza.id(),err); } FPromptRequests.removeAll(AStanza.id()); } else if (FUserJidRequests.contains(AStanza.id())) { if (AStanza.type() == "result") { LOG_STRM_DEBUG(AStreamJid,QString("Legacy user JID received, id=%1").arg(AStanza.id())); Jid userJid = AStanza.firstElement("query",NS_JABBER_GATEWAY).firstChildElement("jid").text(); emit userJidReceived(AStanza.id(),userJid); } else { XmppStanzaError err(AStanza); LOG_STRM_WARNING(AStreamJid,QString("Failed to receive legacy user JID, id=%1: %2").arg(AStanza.id(),err.condition())); emit errorReceived(AStanza.id(),err); } FUserJidRequests.removeAll(AStanza.id()); } }
bool PrivateStorage::stanzaReadWrite(int AHandleId, const Jid &AStreamJid, Stanza &AStanza, bool &AAccept) { if (AHandleId == FSHINotifyDataChanged) { AAccept = true; QDomElement dataElem = AStanza.firstElement("x",NS_VACUUM_PRIVATESTORAGE_UPDATE).firstChildElement(); while (!dataElem.isNull()) { LOG_STRM_INFO(AStreamJid,QString("Private data update notify received, ns=%1").arg(dataElem.namespaceURI())); emit dataChanged(AStreamJid,dataElem.tagName(),dataElem.namespaceURI()); dataElem = dataElem.nextSiblingElement(); } return true; } return false; }
bool MessageCarbons::stanzaReadWrite(int AHandleId, const Jid &AStreamJid, Stanza &AStanza, bool &AAccept) { if (isEnabled(AStreamJid) && FSHIForwards.value(AStreamJid)==AHandleId) { QDomElement fwdElem = AStanza.firstElement("forwarded",NS_MESSAGE_FORWARD); bool isSent = !Stanza::findElement(fwdElem,"sent",NS_MESSAGE_CARBONS).isNull(); bool isReceived = !Stanza::findElement(fwdElem,"received",NS_MESSAGE_CARBONS).isNull(); QDomElement msgElem = Stanza::findElement(fwdElem,"message"); if (!msgElem.isNull() && (isSent || isReceived)) { AAccept = true; Stanza stanza(msgElem); Message message(stanza); if (isSent) { message.stanza().addElement("sent",NS_MESSAGE_CARBONS); if (FMessageProcessor) { if (FMessageProcessor->processMessage(AStreamJid,message,IMessageProcessor::MessageOut)) FMessageProcessor->displayMessage(AStreamJid,message,IMessageProcessor::MessageOut); } emit messageSent(AStreamJid,message); } else { message.stanza().addElement("received",NS_MESSAGE_CARBONS); if (FMessageProcessor) { if (FMessageProcessor->processMessage(AStreamJid,message,IMessageProcessor::MessageIn)) FMessageProcessor->displayMessage(AStreamJid,message,IMessageProcessor::MessageIn); } emit messageReceived(AStreamJid,message); } } } return false; }
bool RegisterStream::xmppStanzaIn(IXmppStream *AXmppStream, Stanza &AStanza, int AOrder) { if (AXmppStream==FXmppStream && AOrder==XSHO_XMPP_FEATURE) { if (AStanza.id() == "getReg") { if (AStanza.type() == "result") { LOG_STRM_INFO(AXmppStream->streamJid(),"Account registration fileds loaded"); QDomElement queryElem = AStanza.firstElement("query",NS_JABBER_REGISTER); QDomElement formElem = Stanza::findElement(queryElem,"x",NS_JABBER_DATA); if (FDataForms && !formElem.isNull()) { IDataForm form = FDataForms->dataForm(formElem); if (FDataForms->isFormValid(form)) { int userFiled = FDataForms->fieldIndex("username",form.fields); if (userFiled >= 0) { form.fields[userFiled].value = FXmppStream->streamJid().node(); form.fields[userFiled].type = DATAFIELD_TYPE_HIDDEN; } int passFiled = FDataForms->fieldIndex("password",form.fields); if (passFiled >= 0) { form.fields[passFiled].value = FXmppStream->getSessionPassword(); form.fields[passFiled].type = DATAFIELD_TYPE_HIDDEN; } FDialog = FDataForms->dialogWidget(form,NULL); FDialog->setAllowInvalid(false); FDialog->instance()->setWindowTitle(tr("Registration on %1").arg(FXmppStream->streamJid().domain())); connect(FDialog->instance(),SIGNAL(accepted()),SLOT(onRegisterDialogAccepred())); connect(FDialog->instance(),SIGNAL(rejected()),SLOT(onRegisterDialogRejected())); WidgetManager::showActivateRaiseWindow(FDialog->instance()); FXmppStream->setKeepAliveTimerActive(false); LOG_STRM_INFO(AXmppStream->streamJid(),"Account registration form dialog shown"); } else { LOG_STRM_WARNING(AXmppStream->streamJid(),"Failed to register new account on server: Invalid registration form received"); emit error(XmppError(IERR_REGISTER_INVALID_FORM)); } } else { Stanza submit("iq"); submit.setType("set").setId("setReg"); QDomElement querySubmit = submit.addElement("query",NS_JABBER_REGISTER); if (!queryElem.firstChildElement("username").isNull()) querySubmit.appendChild(submit.createElement("username")).appendChild(submit.createTextNode(FXmppStream->streamJid().node())); if (!queryElem.firstChildElement("password").isNull()) querySubmit.appendChild(submit.createElement("password")).appendChild(submit.createTextNode(FXmppStream->getSessionPassword())); if (!queryElem.firstChildElement("key").isNull()) querySubmit.appendChild(submit.createElement("key")).appendChild(submit.createTextNode(AStanza.firstElement("query").attribute("key"))); FXmppStream->sendStanza(submit); LOG_STRM_INFO(AXmppStream->streamJid(),"Account registration submit request sent"); } } else { XmppStanzaError err(AStanza); LOG_STRM_WARNING(AXmppStream->streamJid(),QString("Failed to load account registration fields: %1").arg(err.condition())); emit error(err); } return true; } else if (AStanza.id() == "setReg") { FXmppStream->removeXmppStanzaHandler(XSHO_XMPP_FEATURE,this); if (AStanza.type() == "result") { REPORT_EVENT(SEVP_REGISTRATION_STREAM_SUCCESS,1); LOG_STRM_INFO(AXmppStream->streamJid(),"Account registration submit accepted"); deleteLater(); emit finished(false); } else { XmppStanzaError err(AStanza); LOG_STRM_WARNING(AXmppStream->streamJid(),QString("Account registration submit rejected: %1").arg(err.condition())); emit error(err); } return true; } } return false; }
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; }
//IXmppStanzaHandler bool StanzaProcessor::xmppStanzaIn(IXmppStream *AXmppStream, Stanza &AStanza, int AOrder) { if (AOrder == XSHO_STANZAPROCESSOR) { if (!sendStanzaIn(AXmppStream->streamJid(),AStanza)) { LOG_STRM_DEBUG(AXmppStream->streamJid(),QString("Incoming stanza not accepted, from=%1, kind=%2, ns=%3").arg(AStanza.from(),AStanza.kind(),AStanza.firstElement().namespaceURI())); if (AStanza.kind()==STANZA_KIND_IQ && IqRequestTypes.contains(AStanza.type())) { Stanza error = makeReplyError(AStanza,XmppStanzaError::EC_SERVICE_UNAVAILABLE); sendStanzaOut(AXmppStream->streamJid(), error); } } } return false; }
void JabberSearch::stanzaRequestResult(const Jid &AStreamJid, const Stanza &AStanza) { Q_UNUSED(AStreamJid); if (FRequests.contains(AStanza.id())) { if (AStanza.type() == "result") { LOG_STRM_INFO(AStreamJid,QString("Search request result received, id=%1").arg(AStanza.id())); QDomElement query = AStanza.firstElement("query",NS_JABBER_SEARCH); ISearchFields fields; fields.serviceJid = AStanza.from(); fields.fieldMask = 0; fields.instructions = query.firstChildElement("instructions").text(); if (!query.firstChildElement("first").isNull()) { fields.fieldMask += ISearchFields::First; fields.item.firstName = query.firstChildElement("first").text(); } if (!query.firstChildElement("last").isNull()) { fields.fieldMask += ISearchFields::Last; fields.item.lastName = query.firstChildElement("last").text(); } if (!query.firstChildElement("nick").isNull()) { fields.fieldMask += ISearchFields::Nick; fields.item.nick = query.firstChildElement("nick").text(); } if (!query.firstChildElement("email").isNull()) { fields.fieldMask += ISearchFields::Email; fields.item.email = query.firstChildElement("email").text(); } if (FDataForms) { QDomElement formElem = query.firstChildElement("x"); while (!formElem.isNull() && formElem.namespaceURI()!=NS_JABBER_DATA) formElem = formElem.nextSiblingElement("x"); if (!formElem.isNull()) fields.form = FDataForms->dataForm(formElem); } emit searchFields(AStanza.id(),fields); } else { XmppStanzaError err(AStanza); LOG_STRM_WARNING(AStreamJid,QString("Failed to receive search request result, id=%1: %2").arg(AStanza.id(),err.condition())); emit searchError(AStanza.id(),err); } FRequests.removeAll(AStanza.id()); } else if (FSubmits.contains(AStanza.id())) { if (AStanza.type() == "result") { LOG_STRM_INFO(AStreamJid,QString("Search submit result received, id=%1").arg(AStanza.id())); QDomElement query = AStanza.firstElement("query",NS_JABBER_SEARCH); ISearchResult result; result.serviceJid = AStanza.from(); QDomElement itemElem = query.firstChildElement("item"); while (!itemElem.isNull()) { ISearchItem item; item.itemJid = itemElem.attribute("jid"); item.firstName = itemElem.firstChildElement("first").text(); item.lastName = itemElem.firstChildElement("last").text(); item.nick = itemElem.firstChildElement("nick").text(); item.email = itemElem.firstChildElement("email").text(); result.items.append(item); } if (FDataForms) { QDomElement formElem = query.firstChildElement("x"); while (!formElem.isNull() && formElem.namespaceURI()!=NS_JABBER_DATA) formElem = formElem.nextSiblingElement("x"); if (!formElem.isNull()) result.form = FDataForms->dataForm(formElem); } emit searchResult(AStanza.id(),result); } else { XmppStanzaError err(AStanza); LOG_STRM_WARNING(AStreamJid,QString("Failed to receive search submit result, id=%1: %2").arg(AStanza.id(),err.condition())); emit searchError(AStanza.id(),err); } FSubmits.removeAll(AStanza.id()); } }
void MultiUserChat::stanzaRequestResult(const Jid &AStreamJid, const Stanza &AStanza) { Q_UNUSED(AStreamJid); if (AStanza.id()==FConfigRequestId && FRoomJid==AStanza.from()) { if (AStanza.type() == "result") { LOG_STRM_INFO(AStreamJid,QString("Conference configuretion form received, room=%1").arg(FRoomJid.bare())); QDomElement formElem = AStanza.firstElement("query",NS_MUC_OWNER).firstChildElement("x"); while (formElem.namespaceURI() != NS_JABBER_DATA) formElem = formElem.nextSiblingElement("x"); if (FDataForms && !formElem.isNull()) emit configFormReceived(FDataForms->dataForm(formElem)); else emit chatNotify(tr("Room configuration is not available.")); } else { XmppStanzaError err(AStanza); LOG_STRM_WARNING(AStreamJid,QString("Failed to receive conference configuration form, room=%1: %2").arg(FRoomJid.bare(),err.condition())); emit chatError(err.errorMessage()); } FConfigRequestId.clear(); } else if (AStanza.id()==FConfigSubmitId && FRoomJid==AStanza.from()) { if (AStanza.type() == "result") { LOG_STRM_INFO(AStreamJid,QString("Conference configuration submit accepted, room=%1").arg(FRoomJid.bare())); emit configFormAccepted(); emit chatNotify(tr("Room configuration accepted.")); } else { XmppStanzaError err(AStanza); LOG_STRM_WARNING(AStreamJid,QString("Failed to accept conference configuration submit, room=%1: %2").arg(FRoomJid.bare(),err.condition())); emit configFormRejected(err); emit chatError(err.errorMessage()); } FConfigSubmitId.clear(); } else if (FAffilListRequests.contains(AStanza.id()) && FRoomJid==AStanza.from()) { QString affiliation = FAffilListRequests.take(AStanza.id()); if (AStanza.type() == "result") { LOG_STRM_INFO(AStreamJid,QString("Conference affiliation list received, room=%1, affiliation=%2, id=%3").arg(FRoomJid.bare(),affiliation,AStanza.id())); QList<IMultiUserListItem> listItems; QDomElement itemElem = AStanza.firstElement("query",NS_MUC_ADMIN).firstChildElement("item"); while (!itemElem.isNull()) { if (itemElem.attribute("affiliation") == affiliation) { IMultiUserListItem listitem; listitem.jid = itemElem.attribute("jid"); listitem.affiliation = itemElem.attribute("affiliation"); listitem.notes = itemElem.firstChildElement("reason").text(); listItems.append(listitem); } itemElem = itemElem.nextSiblingElement("item"); } emit affiliationListReceived(affiliation,listItems); } else { XmppStanzaError err(AStanza); LOG_STRM_WARNING(AStreamJid,QString("Failed to receive conference affiliation list, room=%1, affiliation=%2, id=%3: %4").arg(FRoomJid.bare(),affiliation,AStanza.id(),err.condition())); emit chatError(tr("Request for list of %1s is failed: %2").arg(affiliation).arg(err.errorMessage())); } } else if (FAffilListSubmits.contains(AStanza.id()) && FRoomJid==AStanza.from()) { QString affiliation = FAffilListSubmits.take(AStanza.id()); if (AStanza.type() == "result") { LOG_STRM_INFO(AStreamJid,QString("Conference affiliation list changes accepted, room=%1, affiliation=%2, id=%3").arg(FRoomJid.bare(),affiliation,AStanza.id())); emit chatNotify(tr("Changes in list of %1s was accepted.").arg(affiliation)); } else { XmppStanzaError err(AStanza); LOG_STRM_WARNING(AStreamJid,QString("Failed to accept conference affiliation list changes, room=%1, affiliation=%2, id=%3: %4").arg(FRoomJid.bare(),affiliation,AStanza.id(),err.condition())); emit chatError(tr("Changes in list of %1s was not accepted: %2").arg(affiliation).arg(err.errorMessage())); } } else if (AStanza.type() == "error") { XmppStanzaError err(AStanza); LOG_STRM_WARNING(AStreamJid,QString("Unexpected error received in conference, room=%1, id=%2: %3").arg(FRoomJid.bare(),AStanza.id(),err.condition())); emit chatError(err.errorMessage()); } }
bool Presence::stanzaReadWrite(int AHandlerId, const Jid &AStreamJid, Stanza &AStanza, bool &AAccept) { if (AHandlerId == FSHIPresence) { int show; int priority; QString status; QString errCond; if (AStanza.type().isEmpty()) { QString showText = AStanza.firstElement("show").text(); if (showText.isEmpty()) show = Online; else if (showText == "chat") show = Chat; else if (showText == "away") show = Away; else if (showText == "dnd") show = DoNotDisturb; else if (showText == "xa") show = ExtendedAway; else show = Online; //Костыль под кривые клиенты и транспорты status = AStanza.firstElement("status").text(); priority = AStanza.firstElement("priority").text().toInt(); } else if (AStanza.type() == "unavailable") { show = Offline; status = AStanza.firstElement("status").text(); priority = 0; } else if (AStanza.type() == "error") { ErrorHandler err(AStanza.element()); show = Error; status = err.message(); errCond = err.condition(); priority = 0; } else return false; if (AStreamJid != AStanza.from()) { Jid fromJid = AStanza.from(); IPresenceItem &pitem = FItems[fromJid]; IPresenceItem before = pitem; pitem.isValid = true; pitem.itemJid = fromJid; pitem.show = show; pitem.priority = priority; pitem.status = status; pitem.errCondition = errCond; if (pitem != before) emit itemReceived(pitem, before); if (show == Offline) FItems.remove(fromJid); } else if (show!=IPresence::Offline && (FShow != show || FStatus != status || FPriority != priority)) { LogDetaile(QString("[Presence][%1] Self presence changed by server, show=%2, status='%3'").arg(streamJid().bare()).arg(show).arg(status)); FShow = show; FStatus = status; FPriority = priority; FErrCondition = errCond; emit changed(show,status,priority); } AAccept = true; } return false; }
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; }