diff options
author | Remko Tronçon <git@el-tramo.be> | 2011-08-28 09:19:46 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2011-08-28 09:19:46 (GMT) |
commit | 5f1cb0d768265347bc80862c33f5967f07759b10 (patch) | |
tree | 979eceddcd0f5e6a651180b91d0908e1e1e319b7 /Swiften/Queries | |
parent | 8dbae452004e7bc3c3a6e855f365b9bb348e8f2d (diff) | |
download | swift-5f1cb0d768265347bc80862c33f5967f07759b10.zip swift-5f1cb0d768265347bc80862c33f5967f07759b10.tar.bz2 |
Check sender on incoming IQ responses.
Release-Notes: Fixed a bug whereby the sender of an iq wasn't being checked before matching it to a request.
Diffstat (limited to 'Swiften/Queries')
-rw-r--r-- | Swiften/Queries/IQRouter.h | 15 | ||||
-rw-r--r-- | Swiften/Queries/Request.cpp | 47 | ||||
-rw-r--r-- | Swiften/Queries/Request.h | 2 | ||||
-rw-r--r-- | Swiften/Queries/UnitTest/RequestTest.cpp | 95 |
4 files changed, 134 insertions, 25 deletions
diff --git a/Swiften/Queries/IQRouter.h b/Swiften/Queries/IQRouter.h index 312dca8..a21b24d 100644 --- a/Swiften/Queries/IQRouter.h +++ b/Swiften/Queries/IQRouter.h @@ -22,6 +22,20 @@ namespace Swift { ~IQRouter(); /** + * Sets the JID of this IQ router. + * + * This JID is used by requests to check whether incoming + * results are addressed correctly. + */ + void setJID(const JID& jid) { + jid_ = jid; + } + + const JID& getJID() { + return jid_; + } + + /** * Sets the 'from' JID for all outgoing IQ stanzas. * * By default, IQRouter does not add a from to IQ stanzas, since @@ -55,6 +69,7 @@ namespace Swift { private: IQChannel* channel_; + JID jid_; JID from_; std::vector< boost::shared_ptr<IQHandler> > handlers_; std::vector< boost::shared_ptr<IQHandler> > queuedRemoves_; diff --git a/Swiften/Queries/Request.cpp b/Swiften/Queries/Request.cpp index a77cf49..0ffae26 100644 --- a/Swiften/Queries/Request.cpp +++ b/Swiften/Queries/Request.cpp @@ -41,27 +41,46 @@ bool Request::handleIQ(boost::shared_ptr<IQ> iq) { bool handled = false; if (iq->getType() == IQ::Result || iq->getType() == IQ::Error) { if (sent_ && iq->getID() == id_) { - if (iq->getType() == IQ::Result) { - 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>(); - if (errorPayload) { - handleResponse(boost::shared_ptr<Payload>(), errorPayload); + if (isCorrectSender(iq->getFrom())) { + if (iq->getType() == IQ::Result) { + 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 { - handleResponse(boost::shared_ptr<Payload>(), ErrorPayload::ref(new ErrorPayload(ErrorPayload::UndefinedCondition))); + ErrorPayload::ref errorPayload = iq->getPayload<ErrorPayload>(); + if (errorPayload) { + handleResponse(boost::shared_ptr<Payload>(), errorPayload); + } + else { + handleResponse(boost::shared_ptr<Payload>(), ErrorPayload::ref(new ErrorPayload(ErrorPayload::UndefinedCondition))); + } } + router_->removeHandler(this); + handled = true; } - router_->removeHandler(this); - handled = true; } } return handled; } +bool Request::isCorrectSender(const JID& jid) { + if (isAccountJID(receiver_)) { + return isAccountJID(jid); + } + else { + return jid.equals(receiver_, JID::WithResource); + } +} + +bool Request::isAccountJID(const JID& jid) { + // If the router's JID is not set, we don't check anything + if (!router_->getJID().isValid()) { + return true; + } + return jid.isValid() ? router_->getJID().equals(jid, JID::WithoutResource) : true; +} + } diff --git a/Swiften/Queries/Request.h b/Swiften/Queries/Request.h index eee89e9..c710548 100644 --- a/Swiften/Queries/Request.h +++ b/Swiften/Queries/Request.h @@ -60,6 +60,8 @@ namespace Swift { private: bool handleIQ(boost::shared_ptr<IQ>); + bool isCorrectSender(const JID& jid); + bool isAccountJID(const JID& jid); private: IQRouter* router_; diff --git a/Swiften/Queries/UnitTest/RequestTest.cpp b/Swiften/Queries/UnitTest/RequestTest.cpp index 46eb6fd..b3925dd 100644 --- a/Swiften/Queries/UnitTest/RequestTest.cpp +++ b/Swiften/Queries/UnitTest/RequestTest.cpp @@ -31,6 +31,11 @@ class RequestTest : public CppUnit::TestFixture { CPPUNIT_TEST(testHandleIQ_RawXMLPayload); CPPUNIT_TEST(testHandleIQ_GetWithSameID); CPPUNIT_TEST(testHandleIQ_SetWithSameID); + CPPUNIT_TEST(testHandleIQ_IncorrectSender); + CPPUNIT_TEST(testHandleIQ_IncorrectSenderForServerQuery); + CPPUNIT_TEST(testHandleIQ_ServerRespondsWithDomain); + CPPUNIT_TEST(testHandleIQ_ServerRespondsWithBareJID); + CPPUNIT_TEST(testHandleIQ_ServerRespondsWithoutFrom); CPPUNIT_TEST_SUITE_END(); public: @@ -98,7 +103,7 @@ class RequestTest : public CppUnit::TestFixture { testling.onResponse.connect(boost::bind(&RequestTest::handleResponse, this, _1, _2)); testling.send(); - channel_->onIQReceived(createResponse("test-id")); + channel_->onIQReceived(createResponse(JID("foo@bar.com/baz"),"test-id")); CPPUNIT_ASSERT_EQUAL(1, responsesReceived_); CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(receivedErrors.size())); @@ -111,7 +116,7 @@ class RequestTest : public CppUnit::TestFixture { testling.onResponse.connect(boost::bind(&RequestTest::handleResponse, this, _1, _2)); testling.send(); - channel_->onIQReceived(createResponse("different-id")); + channel_->onIQReceived(createResponse(JID("foo@bar.com/baz"),"different-id")); CPPUNIT_ASSERT_EQUAL(0, responsesReceived_); CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(receivedErrors.size())); @@ -123,7 +128,7 @@ class RequestTest : public CppUnit::TestFixture { testling.onResponse.connect(boost::bind(&RequestTest::handleResponse, this, _1, _2)); testling.send(); - boost::shared_ptr<IQ> error = createError("test-id"); + boost::shared_ptr<IQ> error = createError(JID("foo@bar.com/baz"),"test-id"); boost::shared_ptr<Payload> errorPayload = boost::shared_ptr<ErrorPayload>(new ErrorPayload(ErrorPayload::InternalServerError)); error->addPayload(errorPayload); channel_->onIQReceived(error); @@ -139,7 +144,7 @@ class RequestTest : public CppUnit::TestFixture { testling.onResponse.connect(boost::bind(&RequestTest::handleResponse, this, _1, _2)); testling.send(); - channel_->onIQReceived(createError("test-id")); + channel_->onIQReceived(createError(JID("foo@bar.com/baz"),"test-id")); CPPUNIT_ASSERT_EQUAL(0, responsesReceived_); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(receivedErrors.size())); @@ -150,7 +155,7 @@ class RequestTest : public CppUnit::TestFixture { void testHandleIQ_BeforeSend() { MyRequest testling(IQ::Get, JID("foo@bar.com/baz"), payload_, router_); testling.onResponse.connect(boost::bind(&RequestTest::handleResponse, this, _1, _2)); - channel_->onIQReceived(createResponse("test-id")); + channel_->onIQReceived(createResponse(JID("foo@bar.com/baz"),"test-id")); CPPUNIT_ASSERT_EQUAL(0, responsesReceived_); CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(receivedErrors.size())); @@ -163,7 +168,7 @@ class RequestTest : public CppUnit::TestFixture { testling.send(); responsePayload_ = boost::make_shared<MyOtherPayload>(); - channel_->onIQReceived(createResponse("test-id")); + channel_->onIQReceived(createResponse(JID("foo@bar.com/baz"),"test-id")); CPPUNIT_ASSERT_EQUAL(1, responsesReceived_); CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(receivedErrors.size())); @@ -177,7 +182,7 @@ class RequestTest : public CppUnit::TestFixture { testling.send(); responsePayload_ = boost::make_shared<MyOtherPayload>(); - channel_->onIQReceived(createResponse("test-id")); + channel_->onIQReceived(createResponse(JID("foo@bar.com/baz"),"test-id")); CPPUNIT_ASSERT_EQUAL(1, responsesReceived_); CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(receivedErrors.size())); @@ -189,7 +194,7 @@ class RequestTest : public CppUnit::TestFixture { testling.onResponse.connect(boost::bind(&RequestTest::handleResponse, this, _1, _2)); testling.send(); - boost::shared_ptr<IQ> response = createResponse("test-id"); + boost::shared_ptr<IQ> response = createResponse(JID("foo@bar.com/baz"),"test-id"); response->setType(IQ::Get); channel_->onIQReceived(response); @@ -203,7 +208,7 @@ class RequestTest : public CppUnit::TestFixture { testling.onResponse.connect(boost::bind(&RequestTest::handleResponse, this, _1, _2)); testling.send(); - boost::shared_ptr<IQ> response = createResponse("test-id"); + boost::shared_ptr<IQ> response = createResponse(JID("foo@bar.com/baz"), "test-id"); response->setType(IQ::Set); channel_->onIQReceived(response); @@ -212,6 +217,72 @@ class RequestTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(channel_->iqs_.size())); } + void testHandleIQ_IncorrectSender() { + MyRequest testling(IQ::Get, JID("foo@bar.com/baz"), payload_, router_); + router_->setJID("alice@wonderland.lit/TeaParty"); + testling.onResponse.connect(boost::bind(&RequestTest::handleResponse, this, _1, _2)); + testling.send(); + + channel_->onIQReceived(createResponse(JID("anotherfoo@bar.com/baz"), "test-id")); + + CPPUNIT_ASSERT_EQUAL(0, responsesReceived_); + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(receivedErrors.size())); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(channel_->iqs_.size())); + } + + void testHandleIQ_IncorrectSenderForServerQuery() { + MyRequest testling(IQ::Get, JID(), payload_, router_); + router_->setJID("alice@wonderland.lit/TeaParty"); + testling.onResponse.connect(boost::bind(&RequestTest::handleResponse, this, _1, _2)); + testling.send(); + + channel_->onIQReceived(createResponse(JID("foo@bar.com/baz"), "test-id")); + + CPPUNIT_ASSERT_EQUAL(0, responsesReceived_); + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(receivedErrors.size())); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(channel_->iqs_.size())); + } + + void testHandleIQ_ServerRespondsWithDomain() { + MyRequest testling(IQ::Get, JID(), payload_, router_); + router_->setJID("alice@wonderland.lit/TeaParty"); + testling.onResponse.connect(boost::bind(&RequestTest::handleResponse, this, _1, _2)); + testling.send(); + + channel_->onIQReceived(createResponse(JID("wonderland.lit"),"test-id")); + + CPPUNIT_ASSERT_EQUAL(0, responsesReceived_); + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(receivedErrors.size())); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(channel_->iqs_.size())); + } + + void testHandleIQ_ServerRespondsWithBareJID() { + MyRequest testling(IQ::Get, JID(), payload_, router_); + router_->setJID("alice@wonderland.lit/TeaParty"); + testling.onResponse.connect(boost::bind(&RequestTest::handleResponse, this, _1, _2)); + testling.send(); + + channel_->onIQReceived(createResponse(JID("alice@wonderland.lit"),"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_ServerRespondsWithoutFrom() { + MyRequest testling(IQ::Get, JID(), payload_, router_); + router_->setJID("alice@wonderland.lit/TeaParty"); + testling.onResponse.connect(boost::bind(&RequestTest::handleResponse, this, _1, _2)); + testling.send(); + + channel_->onIQReceived(createResponse(JID(),"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) { @@ -239,15 +310,17 @@ class RequestTest : public CppUnit::TestFixture { ++responsesReceived_; } - boost::shared_ptr<IQ> createResponse(const std::string& id) { + boost::shared_ptr<IQ> createResponse(const JID& from, const std::string& id) { boost::shared_ptr<IQ> iq(new IQ(IQ::Result)); + iq->setFrom(from); iq->addPayload(responsePayload_); iq->setID(id); return iq; } - boost::shared_ptr<IQ> createError(const std::string& id) { + boost::shared_ptr<IQ> createError(const JID& from, const std::string& id) { boost::shared_ptr<IQ> iq(new IQ(IQ::Error)); + iq->setFrom(from); iq->setID(id); return iq; } |