summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften')
-rw-r--r--Swiften/Client/ClientSession.cpp3
-rw-r--r--Swiften/Client/ClientSession.h11
-rw-r--r--Swiften/Client/CoreClient.cpp18
-rw-r--r--Swiften/Client/CoreClient.h16
-rw-r--r--Swiften/Client/UnitTest/ClientSessionTest.cpp3
-rw-r--r--Swiften/Component/UnitTest/ComponentSessionTest.cpp3
-rw-r--r--Swiften/Elements/RawXMLPayload.h7
-rw-r--r--Swiften/Queries/RawRequest.h49
-rw-r--r--Swiften/Queries/Request.cpp7
-rw-r--r--Swiften/Queries/UnitTest/RequestTest.cpp65
-rw-r--r--Swiften/Session/BasicSessionStream.cpp5
-rw-r--r--Swiften/Session/BasicSessionStream.h1
-rw-r--r--Swiften/Session/SessionStream.h1
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;