示例#1
0
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;
}
示例#2
0
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));
		}
	}
}
示例#3
0
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;
}
示例#4
0
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());
	}
}
示例#5
0
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;
}
示例#6
0
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;
}
示例#7
0
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);
	}
}
示例#8
0
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());
	}
}
示例#9
0
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;
}
示例#10
0
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;
}
示例#11
0
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;
}
示例#12
0
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;
}
示例#13
0
//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;
}
示例#14
0
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());
    }
}
示例#15
0
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());
	}
}
示例#16
0
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;
}
示例#17
0
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);
	}
}
示例#18
0
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;
}