Exemplo n.º 1
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());
	}
}
Exemplo n.º 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));
		}
	}
}
Exemplo n.º 3
0
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);
	}
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
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);
	}
}
Exemplo n.º 6
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);
	}
}
Exemplo n.º 7
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;
}