diff options
Diffstat (limited to 'Swiften')
-rw-r--r-- | Swiften/Client/ClientSession.cpp | 3 | ||||
-rw-r--r-- | Swiften/Client/ClientSession.h | 11 | ||||
-rw-r--r-- | Swiften/Client/CoreClient.cpp | 18 | ||||
-rw-r--r-- | Swiften/Client/CoreClient.h | 16 | ||||
-rw-r--r-- | Swiften/Client/UnitTest/ClientSessionTest.cpp | 3 | ||||
-rw-r--r-- | Swiften/Component/UnitTest/ComponentSessionTest.cpp | 3 | ||||
-rw-r--r-- | Swiften/Elements/RawXMLPayload.h | 7 | ||||
-rw-r--r-- | Swiften/Queries/RawRequest.h | 49 | ||||
-rw-r--r-- | Swiften/Queries/Request.cpp | 7 | ||||
-rw-r--r-- | Swiften/Queries/UnitTest/RequestTest.cpp | 65 | ||||
-rw-r--r-- | Swiften/Session/BasicSessionStream.cpp | 5 | ||||
-rw-r--r-- | Swiften/Session/BasicSessionStream.h | 1 | ||||
-rw-r--r-- | Swiften/Session/SessionStream.h | 1 |
13 files changed, 182 insertions, 7 deletions
diff --git a/Swiften/Client/ClientSession.cpp b/Swiften/Client/ClientSession.cpp index 8d9e678..e1c1d8e 100644 --- a/Swiften/Client/ClientSession.cpp +++ b/Swiften/Client/ClientSession.cpp @@ -50,6 +50,7 @@ ClientSession::ClientSession( stream(stream), allowPLAINOverNonTLS(false), useStreamCompression(true), + useTLS(UseTLSWhenAvailable), needSessionStart(false), needResourceBind(false), needAcking(false), @@ -170,7 +171,7 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) { return; } - if (streamFeatures->hasStartTLS() && stream->supportsTLSEncryption()) { + if (streamFeatures->hasStartTLS() && stream->supportsTLSEncryption() && useTLS != NeverUseTLS) { state = WaitingForEncrypt; stream->writeElement(boost::shared_ptr<StartTLSRequest>(new StartTLSRequest())); } diff --git a/Swiften/Client/ClientSession.h b/Swiften/Client/ClientSession.h index ee3992d..25ee694 100644 --- a/Swiften/Client/ClientSession.h +++ b/Swiften/Client/ClientSession.h @@ -57,6 +57,11 @@ namespace Swift { Error(Type type) : type(type) {} }; + enum UseTLS { + NeverUseTLS, + UseTLSWhenAvailable + }; + ~ClientSession(); static boost::shared_ptr<ClientSession> create(const JID& jid, boost::shared_ptr<SessionStream> stream) { @@ -75,6 +80,11 @@ namespace Swift { useStreamCompression = b; } + void setUseTLS(UseTLS b) { + useTLS = b; + } + + bool getStreamManagementEnabled() const { return stanzaAckRequester_; } @@ -139,6 +149,7 @@ namespace Swift { boost::shared_ptr<SessionStream> stream; bool allowPLAINOverNonTLS; bool useStreamCompression; + UseTLS useTLS; bool needSessionStart; bool needResourceBind; bool needAcking; diff --git a/Swiften/Client/CoreClient.cpp b/Swiften/Client/CoreClient.cpp index a199b16..f0c5333 100644 --- a/Swiften/Client/CoreClient.cpp +++ b/Swiften/Client/CoreClient.cpp @@ -22,7 +22,7 @@ namespace Swift { -CoreClient::CoreClient(const JID& jid, const std::string& password, NetworkFactories* networkFactories) : jid_(jid), password_(password), networkFactories(networkFactories), useStreamCompression(true), disconnectRequested_(false), certificateTrustChecker(NULL) { +CoreClient::CoreClient(const JID& jid, const std::string& password, NetworkFactories* networkFactories) : jid_(jid), password_(password), networkFactories(networkFactories), useStreamCompression(true), useTLS(UseTLSWhenAvailable), disconnectRequested_(false), certificateTrustChecker(NULL) { stanzaChannel_ = new ClientSessionStanzaChannel(); stanzaChannel_->onMessageReceived.connect(boost::bind(&CoreClient::handleMessageReceived, this, _1)); stanzaChannel_->onPresenceReceived.connect(boost::bind(&CoreClient::handlePresenceReceived, this, _1)); @@ -83,6 +83,14 @@ void CoreClient::handleConnectorFinished(boost::shared_ptr<Connection> connectio session_ = ClientSession::create(jid_, sessionStream_); session_->setCertificateTrustChecker(certificateTrustChecker); session_->setUseStreamCompression(useStreamCompression); + switch(useTLS) { + case UseTLSWhenAvailable: + session_->setUseTLS(ClientSession::UseTLSWhenAvailable); + break; + case NeverUseTLS: + session_->setUseTLS(ClientSession::NeverUseTLS); + break; + } stanzaChannel_->setSession(session_); session_->onFinished.connect(boost::bind(&CoreClient::handleSessionFinished, this, _1)); session_->onNeedCredentials.connect(boost::bind(&CoreClient::handleNeedCredentials, this)); @@ -242,6 +250,10 @@ void CoreClient::sendPresence(boost::shared_ptr<Presence> presence) { stanzaChannel_->sendPresence(presence); } +void CoreClient::sendData(const std::string& data) { + sessionStream_->writeData(data); +} + bool CoreClient::isActive() const { return (session_ && !session_->isFinished()) || connector_; } @@ -267,5 +279,9 @@ void CoreClient::setUseStreamCompression(bool b) { useStreamCompression = b; } +void CoreClient::setUseTLS(UseTLS b) { + useTLS = b; +} + } diff --git a/Swiften/Client/CoreClient.h b/Swiften/Client/CoreClient.h index ee73396..eb9c42c 100644 --- a/Swiften/Client/CoreClient.h +++ b/Swiften/Client/CoreClient.h @@ -48,6 +48,11 @@ namespace Swift { */ class CoreClient : public Entity { public: + enum UseTLS { + NeverUseTLS, + UseTLSWhenAvailable + }; + /** * Constructs a client for the given JID with the given password. * The given eventLoop will be used to post events to. @@ -83,6 +88,11 @@ namespace Swift { void sendPresence(Presence::ref); /** + * Sends raw, unchecked data. + */ + void sendData(const std::string& data); + + /** * Returns the IQ router for this client. */ IQRouter* getIQRouter() const { @@ -148,6 +158,11 @@ namespace Swift { */ void setUseStreamCompression(bool b); + /** + * Sets whether TLS encryption should be used. + */ + void setUseTLS(UseTLS useTLS); + public: /** * Emitted when the client was disconnected from the network. @@ -213,6 +228,7 @@ namespace Swift { std::string password_; NetworkFactories* networkFactories; bool useStreamCompression; + UseTLS useTLS; ClientSessionStanzaChannel* stanzaChannel_; IQRouter* iqRouter_; Connector::ref connector_; diff --git a/Swiften/Client/UnitTest/ClientSessionTest.cpp b/Swiften/Client/UnitTest/ClientSessionTest.cpp index 21c0ffb..756287c 100644 --- a/Swiften/Client/UnitTest/ClientSessionTest.cpp +++ b/Swiften/Client/UnitTest/ClientSessionTest.cpp @@ -329,6 +329,9 @@ class ClientSessionTest : public CppUnit::TestFixture { receivedEvents.push_back(Event(element)); } + virtual void writeData(const std::string&) { + } + virtual bool supportsTLSEncryption() { return canTLSEncrypt; } diff --git a/Swiften/Component/UnitTest/ComponentSessionTest.cpp b/Swiften/Component/UnitTest/ComponentSessionTest.cpp index af8962a..953973c 100644 --- a/Swiften/Component/UnitTest/ComponentSessionTest.cpp +++ b/Swiften/Component/UnitTest/ComponentSessionTest.cpp @@ -115,6 +115,9 @@ class ComponentSessionTest : public CppUnit::TestFixture { receivedEvents.push_back(Event(element)); } + virtual void writeData(const std::string&) { + } + virtual bool supportsTLSEncryption() { return false; } diff --git a/Swiften/Elements/RawXMLPayload.h b/Swiften/Elements/RawXMLPayload.h index b042b95..e583c12 100644 --- a/Swiften/Elements/RawXMLPayload.h +++ b/Swiften/Elements/RawXMLPayload.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2011 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ @@ -7,12 +7,13 @@ #pragma once #include <string> -#include "Swiften/Elements/Payload.h" + +#include <Swiften/Elements/Payload.h> namespace Swift { class RawXMLPayload : public Payload { public: - RawXMLPayload() {} + RawXMLPayload(const std::string& data = "") : rawXML_(data) {} void setRawXML(const std::string& data) { rawXML_ = data; diff --git a/Swiften/Queries/RawRequest.h b/Swiften/Queries/RawRequest.h new file mode 100644 index 0000000..477952f --- /dev/null +++ b/Swiften/Queries/RawRequest.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <boost/smart_ptr/make_shared.hpp> +#include <typeinfo> + +#include <Swiften/Queries/Request.h> +#include <Swiften/Elements/RawXMLPayload.h> +#include <Swiften/Elements/ErrorPayload.h> +#include <Swiften/Serializer/PayloadSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/ErrorSerializer.h> +#include <Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h> + +namespace Swift { + class RawRequest : public Request { + public: + typedef boost::shared_ptr<RawRequest> ref; + + static ref create(IQ::Type type, const JID& recipient, const std::string& data, IQRouter* router) { + return ref(new RawRequest(type, recipient, data, router)); + } + + boost::signal<void (const std::string&)> onResponse; + + private: + RawRequest(IQ::Type type, const JID& receiver, const std::string& data, IQRouter* router) : Request(type, receiver, boost::make_shared<RawXMLPayload>(data), router) { + } + + virtual void handleResponse(Payload::ref payload, ErrorPayload::ref error) { + if (error) { + onResponse(ErrorSerializer().serializePayload(error)); + } + else { + assert(payload); + PayloadSerializer* serializer = serializers.getPayloadSerializer(payload); + assert(serializer); + onResponse(serializer->serialize(payload)); + } + } + + private: + FullPayloadSerializerCollection serializers; + }; +} diff --git a/Swiften/Queries/Request.cpp b/Swiften/Queries/Request.cpp index 35475c1..6c47725 100644 --- a/Swiften/Queries/Request.cpp +++ b/Swiften/Queries/Request.cpp @@ -6,6 +6,7 @@ #include "Swiften/Queries/Request.h" #include "Swiften/Queries/IQRouter.h" +#include <Swiften/Elements/RawXMLPayload.h> namespace Swift { @@ -40,7 +41,11 @@ bool Request::handleIQ(boost::shared_ptr<IQ> iq) { bool handled = false; if (sent_ && iq->getID() == id_) { if (iq->getType() == IQ::Result) { - handleResponse(iq->getPayloadOfSameType(payload_), ErrorPayload::ref()); + boost::shared_ptr<Payload> payload = iq->getPayloadOfSameType(payload_); + if (!payload && boost::dynamic_pointer_cast<RawXMLPayload>(payload_) && !iq->getPayloads().empty()) { + payload = iq->getPayloads().front(); + } + handleResponse(payload, ErrorPayload::ref()); } else { ErrorPayload::ref errorPayload = iq->getPayload<ErrorPayload>(); diff --git a/Swiften/Queries/UnitTest/RequestTest.cpp b/Swiften/Queries/UnitTest/RequestTest.cpp index e99149e..34d07c9 100644 --- a/Swiften/Queries/UnitTest/RequestTest.cpp +++ b/Swiften/Queries/UnitTest/RequestTest.cpp @@ -8,11 +8,13 @@ #include <cppunit/extensions/TestFactoryRegistry.h> #include <boost/shared_ptr.hpp> #include <boost/bind.hpp> +#include <boost/smart_ptr/make_shared.hpp> #include "Swiften/Queries/GenericRequest.h" #include "Swiften/Queries/IQRouter.h" #include "Swiften/Queries/DummyIQChannel.h" #include "Swiften/Elements/Payload.h" +#include <Swiften/Elements/RawXMLPayload.h> using namespace Swift; @@ -25,6 +27,8 @@ class RequestTest : public CppUnit::TestFixture { CPPUNIT_TEST(testHandleIQ_Error); CPPUNIT_TEST(testHandleIQ_ErrorWithoutPayload); CPPUNIT_TEST(testHandleIQ_BeforeSend); + CPPUNIT_TEST(testHandleIQ_DifferentPayload); + CPPUNIT_TEST(testHandleIQ_RawXMLPayload); CPPUNIT_TEST_SUITE_END(); public: @@ -34,7 +38,26 @@ class RequestTest : public CppUnit::TestFixture { std::string text_; }; - typedef GenericRequest<MyPayload> MyRequest; + struct MyOtherPayload : public Payload { + }; + + class MyRequest : public Request { + public: + MyRequest( + IQ::Type type, + const JID& receiver, + boost::shared_ptr<Payload> payload, + IQRouter* router) : + Request(type, receiver, payload, router) { + } + + virtual void handleResponse(boost::shared_ptr<Payload> payload, ErrorPayload::ref error) { + onResponse(payload, error); + } + + public: + boost::signal<void (boost::shared_ptr<Payload>, ErrorPayload::ref)> onResponse; + }; public: void setUp() { @@ -132,6 +155,33 @@ class RequestTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(channel_->iqs_.size())); } + void testHandleIQ_DifferentPayload() { + MyRequest testling(IQ::Get, JID("foo@bar.com/baz"), payload_, router_); + testling.onResponse.connect(boost::bind(&RequestTest::handleDifferentResponse, this, _1, _2)); + testling.send(); + + responsePayload_ = boost::make_shared<MyOtherPayload>(); + channel_->onIQReceived(createResponse("test-id")); + + CPPUNIT_ASSERT_EQUAL(1, responsesReceived_); + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(receivedErrors.size())); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(channel_->iqs_.size())); + } + + void testHandleIQ_RawXMLPayload() { + payload_ = boost::make_shared<RawXMLPayload>("<bla/>"); + MyRequest testling(IQ::Get, JID("foo@bar.com/baz"), payload_, router_); + testling.onResponse.connect(boost::bind(&RequestTest::handleRawXMLResponse, this, _1, _2)); + testling.send(); + + responsePayload_ = boost::make_shared<MyOtherPayload>(); + channel_->onIQReceived(createResponse("test-id")); + + CPPUNIT_ASSERT_EQUAL(1, responsesReceived_); + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(receivedErrors.size())); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(channel_->iqs_.size())); + } + private: void handleResponse(boost::shared_ptr<Payload> p, ErrorPayload::ref e) { if (e) { @@ -145,6 +195,19 @@ class RequestTest : public CppUnit::TestFixture { } } + void handleDifferentResponse(boost::shared_ptr<Payload> p, ErrorPayload::ref e) { + CPPUNIT_ASSERT(!e); + CPPUNIT_ASSERT(!p); + ++responsesReceived_; + } + + void handleRawXMLResponse(boost::shared_ptr<Payload> p, ErrorPayload::ref e) { + CPPUNIT_ASSERT(!e); + CPPUNIT_ASSERT(p); + CPPUNIT_ASSERT(boost::dynamic_pointer_cast<MyOtherPayload>(p)); + ++responsesReceived_; + } + boost::shared_ptr<IQ> createResponse(const std::string& id) { boost::shared_ptr<IQ> iq(new IQ(IQ::Result)); iq->addPayload(responsePayload_); diff --git a/Swiften/Session/BasicSessionStream.cpp b/Swiften/Session/BasicSessionStream.cpp index 1736f80..ddb833e 100644 --- a/Swiften/Session/BasicSessionStream.cpp +++ b/Swiften/Session/BasicSessionStream.cpp @@ -88,6 +88,11 @@ void BasicSessionStream::writeFooter() { xmppLayer->writeFooter(); } +void BasicSessionStream::writeData(const std::string& data) { + assert(available); + xmppLayer->writeData(data); +} + void BasicSessionStream::close() { connection->disconnect(); } diff --git a/Swiften/Session/BasicSessionStream.h b/Swiften/Session/BasicSessionStream.h index 747177a..b3f7421 100644 --- a/Swiften/Session/BasicSessionStream.h +++ b/Swiften/Session/BasicSessionStream.h @@ -42,6 +42,7 @@ namespace Swift { virtual void writeHeader(const ProtocolHeader& header); virtual void writeElement(boost::shared_ptr<Element>); virtual void writeFooter(); + virtual void writeData(const std::string& data); virtual void addZLibCompression(); diff --git a/Swiften/Session/SessionStream.h b/Swiften/Session/SessionStream.h index 017d3d4..2753878 100644 --- a/Swiften/Session/SessionStream.h +++ b/Swiften/Session/SessionStream.h @@ -43,6 +43,7 @@ namespace Swift { virtual void writeHeader(const ProtocolHeader& header) = 0; virtual void writeFooter() = 0; virtual void writeElement(boost::shared_ptr<Element>) = 0; + virtual void writeData(const std::string& data) = 0; virtual void addZLibCompression() = 0; |