Пример #1
0
	void ServerInfoStorage::HandleItemInfo (const QXmppDiscoveryIq& iq)
	{
		auto hasIdentity = [&iq] (const QString& cat, const QString& type) -> bool
		{
			const auto& ids = iq.identities ();
			return std::any_of (ids.begin (), ids.end (),
					[&cat, &type] (const auto& id) { return id.category () == cat && id.type () == type; });
		};
		if (hasIdentity ("proxy", "bytestreams"))
		{
			BytestreamsProxy_ = iq.from ();
			emit bytestreamsProxyChanged (BytestreamsProxy_);
		}
	}
Пример #2
0
	void ServerInfoStorage::HandleItems (const QXmppDiscoveryIq& iq)
	{
		for (const auto& item : iq.items ())
			Conn_->GetDiscoManagerWrapper ()->RequestInfo (item.jid (),
					[this] (const QXmppDiscoveryIq& iq) { HandleItemInfo (iq); },
					false,
					item.node ());
	}
Пример #3
0
void tst_QXmppDiscoveryIq::testDiscovery()
{
    const QByteArray xml(
        "<iq id=\"disco1\" from=\"[email protected]/230193\" type=\"result\">"
        "<query xmlns=\"http://jabber.org/protocol/disco#info\">"
        "<identity category=\"client\" name=\"Exodus 0.9.1\" type=\"pc\"/>"
        "<feature var=\"http://jabber.org/protocol/caps\"/>"
        "<feature var=\"http://jabber.org/protocol/disco#info\"/>"
        "<feature var=\"http://jabber.org/protocol/disco#items\"/>"
        "<feature var=\"http://jabber.org/protocol/muc\"/>"
        "</query>"
        "</iq>");

    QXmppDiscoveryIq disco;
    parsePacket(disco, xml);
    QCOMPARE(disco.verificationString(), QByteArray::fromBase64("QgayPKawpkPSDYmwT/WM94uAlu0="));
    serializePacket(disco, xml);
}
Пример #4
0
void ChatClient::_q_discoveryItemsReceived(const QXmppDiscoveryIq &disco)
{
    // we only want results
    if (!d->discoQueue.removeAll(disco.id()) ||
        disco.type() != QXmppIq::Result)
        return;

    if (disco.from() == configuration().domain() &&
        disco.queryNode().isEmpty()) {
        // root items
        foreach (const QXmppDiscoveryIq::Item &item, disco.items()) {
            if (!item.jid().isEmpty() && item.node().isEmpty()) {
                // get info for item
                const QString id = d->discoManager->requestInfo(item.jid(), item.node());
                if (!id.isEmpty())
                    d->discoQueue.append(id);
            }
        }
    }
Пример #5
0
void tst_QXmppDiscoveryIq::testDiscoveryWithForm()
{
    const QByteArray xml(
        "<iq id=\"disco1\" to=\"[email protected]/chamber\" from=\"[email protected]/230193\" type=\"result\">"
        "<query xmlns=\"http://jabber.org/protocol/disco#info\" node=\"http://psi-im.org#q07IKJEyjvHSyhy//CH0CxmKi8w=\">"
        "<identity xml:lang=\"en\" category=\"client\" name=\"Psi 0.11\" type=\"pc\"/>"
        "<identity xml:lang=\"el\" category=\"client\" name=\"Ψ 0.11\" type=\"pc\"/>"
        "<feature var=\"http://jabber.org/protocol/caps\"/>"
        "<feature var=\"http://jabber.org/protocol/disco#info\"/>"
        "<feature var=\"http://jabber.org/protocol/disco#items\"/>"
        "<feature var=\"http://jabber.org/protocol/muc\"/>"
        "<x xmlns=\"jabber:x:data\" type=\"result\">"
        "<field type=\"hidden\" var=\"FORM_TYPE\">"
        "<value>urn:xmpp:dataforms:softwareinfo</value>"
        "</field>"
        "<field type=\"text-multi\" var=\"ip_version\">"
        "<value>ipv4</value>"
        "<value>ipv6</value>"
        "</field>"
        "<field type=\"text-single\" var=\"os\">"
        "<value>Mac</value>"
        "</field>"
        "<field type=\"text-single\" var=\"os_version\">"
        "<value>10.5.1</value>"
        "</field>"
        "<field type=\"text-single\" var=\"software\">"
        "<value>Psi</value>"
        "</field>"
        "<field type=\"text-single\" var=\"software_version\">"
        "<value>0.11</value>"
        "</field>"
        "</x>"
        "</query>"
        "</iq>");

    QXmppDiscoveryIq disco;
    parsePacket(disco, xml);
    QCOMPARE(disco.verificationString(), QByteArray::fromBase64("q07IKJEyjvHSyhy//CH0CxmKi8w="));
    serializePacket(disco, xml);
}
QXmppDiscoveryIq QXmppDiscoveryManager::capabilities()
{
    QXmppDiscoveryIq iq;
    iq.setType(QXmppIq::Result);
    iq.setQueryType(QXmppDiscoveryIq::InfoQuery);

    // features
    QStringList features;
    features
        << ns_chat_states       // XEP-0085: Chat State Notifications
        << ns_capabilities      // XEP-0115 : Entity Capabilities
        << ns_ping              // XEP-0199: XMPP Ping
        << ns_attention;        // XEP-0224: Attention

    foreach(QXmppClientExtension* extension, client()->extensions())
    {
        if(extension)
            features << extension->discoveryFeatures();
    }

    iq.setFeatures(features);

    // identities
    QList<QXmppDiscoveryIq::Identity> identities;

    QXmppDiscoveryIq::Identity identity;
    identity.setCategory(clientCategory());
    identity.setType(clientType());
    identity.setName(clientName());
    identities << identity;

    foreach(QXmppClientExtension* extension, client()->extensions())
    {
        if(extension)
            identities << extension->discoveryIdentities();
    }

    iq.setIdentities(identities);
    return iq;
}
QString QXmppDiscoveryManager::requestInfo(const QString& jid, const QString& node)
{
    QXmppDiscoveryIq request;
    request.setType(QXmppIq::Get);
    request.setQueryType(QXmppDiscoveryIq::InfoQuery);
    request.setTo(jid);
    if(!node.isEmpty())
        request.setQueryNode(node);
    if(client()->sendPacket(request))
        return request.id();
    else
        return QString();
}
Пример #8
0
bool XmppServerProxy65::handleStanza(const QDomElement &element)
{
    if (element.attribute("to") != d->jid)
        return false;

    if (element.tagName() == "iq" && QXmppDiscoveryIq::isDiscoveryIq(element))
    {
        QXmppDiscoveryIq discoIq;
        discoIq.parse(element);

        if (discoIq.type() == QXmppIq::Get)
        {
            QXmppDiscoveryIq responseIq;
            responseIq.setTo(discoIq.from());
            responseIq.setFrom(discoIq.to());
            responseIq.setId(discoIq.id());
            responseIq.setType(QXmppIq::Result);
            responseIq.setQueryType(discoIq.queryType());

            if (discoIq.queryType() == QXmppDiscoveryIq::InfoQuery)
            {
                QStringList features = QStringList() << ns_disco_info << ns_disco_items << ns_bytestreams;

                QList<QXmppDiscoveryIq::Identity> identities;
                QXmppDiscoveryIq::Identity identity;
                identity.setCategory("proxy");
                identity.setType("bytestreams");
                identity.setName("SOCKS5 Bytestreams");
                identities.append(identity);

                responseIq.setFeatures(features);
                responseIq.setIdentities(identities);
            }

            server()->sendPacket(responseIq);
            return true;
        }
    }
    else if (element.tagName() == "iq" && QXmppByteStreamIq::isByteStreamIq(element))
    {
        QXmppByteStreamIq bsIq;
        bsIq.parse(element);

        if (bsIq.type() == QXmppIq::Get)
        {
            // request for the proxy's network address
            if (d->allowedDomains.contains(QXmppUtils::jidToDomain(bsIq.from()))) {
                QXmppByteStreamIq responseIq;
                responseIq.setType(QXmppIq::Result);
                responseIq.setTo(bsIq.from());
                responseIq.setFrom(bsIq.to());
                responseIq.setId(bsIq.id());

                QList<QXmppByteStreamIq::StreamHost> streamHosts;

                QXmppByteStreamIq::StreamHost streamHost;
                streamHost.setJid(d->jid);
                streamHost.setHost(d->hostAddress.toString());
                streamHost.setPort(d->port);
                streamHosts.append(streamHost);

                responseIq.setStreamHosts(streamHosts);
                server()->sendPacket(responseIq);
            } else {
                QXmppIq responseIq;
                responseIq.setType(QXmppIq::Error);
                responseIq.setTo(bsIq.from());
                responseIq.setFrom(bsIq.to());
                responseIq.setId(bsIq.id());
                responseIq.setError(QXmppStanza::Error(QXmppStanza::Error::Auth, QXmppStanza::Error::Forbidden));
                server()->sendPacket(responseIq);
            }
        }
        else if (bsIq.type() == QXmppIq::Set)
        {
            QString hash = streamHash(bsIq.sid(), bsIq.from(), bsIq.activate());
            QTcpSocketPair *pair = d->pairs.value(hash);

            QXmppIq responseIq;
            responseIq.setTo(bsIq.from());
            responseIq.setFrom(bsIq.to());
            responseIq.setId(bsIq.id());

            if (pair &&
                d->allowedDomains.contains(QXmppUtils::jidToDomain(bsIq.from())))
            {
                if (pair->activate()) {
                    info(QString("Activated connection %1 by %2").arg(hash, bsIq.from()));
                    responseIq.setType(QXmppIq::Result);
                } else {
                    warning(QString("Failed to activate connection %1 by %2").arg(hash, bsIq.from()));
                    responseIq.setType(QXmppIq::Error);
                }
            } else {
                warning(QString("Not activating connection %1 by %2").arg(hash, bsIq.from()));
                responseIq.setType(QXmppIq::Error);
            }
            server()->sendPacket(responseIq);
        }
        return true;
    }
    return false;
}
Пример #9
0
void ChatClient::_q_discoveryInfoReceived(const QXmppDiscoveryIq &disco)
{
    // we only want results
    if (!d->discoQueue.removeAll(disco.id()) ||
        disco.type() != QXmppIq::Result)
        return;

    foreach (const QXmppDiscoveryIq::Identity &id, disco.identities()) {
        // check if it's a conference server
        if (id.category() == QLatin1String("conference") &&
            id.type() == QLatin1String("text")) {
            d->mucServer = disco.from();
            info("Found chat room server " + d->mucServer);
            emit mucServerChanged(d->mucServer);
        }
        // check if it's a diagnostics server
        else if (id.category() == QLatin1String("diagnostics") &&
                 id.type() == QLatin1String("server")) {
            d->diagnosticServer = disco.from();
            info("Found diagnostics server " + d->diagnosticServer);
            emit diagnosticServerChanged(d->diagnosticServer);
        }
#if 0
        // check if it's a publish-subscribe server
        else if (id.category() == QLatin1String("pubsub") &&
                 id.type() == QLatin1String("service")) {
            d->pubSubServer = disco.from();
            info("Found pubsub server " + d->pubSubServer);
            emit pubSubServerChanged(d->pubSubServer);
        }
#endif
        // check if it's a SOCKS5 proxy server
        else if (id.category() == QLatin1String("proxy") &&
                 id.type() == QLatin1String("bytestreams")) {
            info("Found bytestream proxy " + disco.from());
            QXmppTransferManager *transferManager = findExtension<QXmppTransferManager>();
            if (transferManager)
                transferManager->setProxy(disco.from());
        }
        // check if it's a file sharing server
        else if (id.category() == QLatin1String("store") &&
                 id.type() == QLatin1String("file")) {
            d->shareServer = disco.from();
            info("Found share server " + d->shareServer);
            emit shareServerChanged(d->shareServer);
        }
    }

    // if it's the root server, ask for items
    if (disco.from() == configuration().domain() && disco.queryNode().isEmpty()) {
        const QString id = d->discoManager->requestItems(disco.from(), disco.queryNode());
        if (!id.isEmpty())
            d->discoQueue.append(id);
    }
}
bool QXmppDiscoveryManager::handleStanza(const QDomElement &element)
{
    if (element.tagName() == "iq" && QXmppDiscoveryIq::isDiscoveryIq(element))
    {
        QXmppDiscoveryIq receivedIq;
        receivedIq.parse(element);

        if(receivedIq.type() == QXmppIq::Get &&
           receivedIq.queryType() == QXmppDiscoveryIq::InfoQuery &&
           (receivedIq.queryNode().isEmpty() || receivedIq.queryNode().startsWith(d->clientCapabilitiesNode)))
        {
            // respond to query
            QXmppDiscoveryIq qxmppFeatures = capabilities();
            qxmppFeatures.setId(receivedIq.id());
            qxmppFeatures.setTo(receivedIq.from());
            qxmppFeatures.setQueryNode(receivedIq.queryNode());
            client()->sendPacket(qxmppFeatures);
        }
        else if(receivedIq.queryType() == QXmppDiscoveryIq::InfoQuery)
            emit infoReceived(receivedIq);
        else if(receivedIq.queryType() == QXmppDiscoveryIq::ItemsQuery)
            emit itemsReceived(receivedIq);

        return true;
    }
    return false;
}