summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Client')
-rw-r--r--Swiften/Client/BlockList.cpp9
-rw-r--r--Swiften/Client/BlockList.h9
-rw-r--r--Swiften/Client/BlockListImpl.cpp32
-rw-r--r--Swiften/Client/BlockListImpl.h4
-rw-r--r--Swiften/Client/Client.cpp41
-rw-r--r--Swiften/Client/Client.h21
-rw-r--r--Swiften/Client/ClientBlockListManager.cpp46
-rw-r--r--Swiften/Client/ClientBlockListManager.h16
-rw-r--r--Swiften/Client/ClientOptions.h51
-rw-r--r--Swiften/Client/ClientSession.cpp78
-rw-r--r--Swiften/Client/ClientSession.h33
-rw-r--r--Swiften/Client/ClientSessionStanzaChannel.cpp7
-rw-r--r--Swiften/Client/ClientSessionStanzaChannel.h1
-rw-r--r--Swiften/Client/ClientXMLTracer.cpp26
-rw-r--r--Swiften/Client/ClientXMLTracer.h8
-rw-r--r--Swiften/Client/CoreClient.cpp83
-rw-r--r--Swiften/Client/CoreClient.h15
-rw-r--r--Swiften/Client/DummyStanzaChannel.h4
-rw-r--r--Swiften/Client/MemoryStorages.cpp21
-rw-r--r--Swiften/Client/MemoryStorages.h7
-rw-r--r--Swiften/Client/NickManager.h3
-rw-r--r--Swiften/Client/NickResolver.h6
-rw-r--r--Swiften/Client/StanzaChannel.h2
-rw-r--r--Swiften/Client/Storages.h6
-rw-r--r--Swiften/Client/UnitTest/ClientBlockListManagerTest.cpp190
-rw-r--r--Swiften/Client/UnitTest/ClientSessionTest.cpp63
-rw-r--r--Swiften/Client/UnitTest/NickResolverTest.cpp13
-rw-r--r--Swiften/Client/XMLBeautifier.cpp20
-rw-r--r--Swiften/Client/XMLBeautifier.h7
29 files changed, 689 insertions, 133 deletions
diff --git a/Swiften/Client/BlockList.cpp b/Swiften/Client/BlockList.cpp
index 0b2fc12..3ee7864 100644
--- a/Swiften/Client/BlockList.cpp
+++ b/Swiften/Client/BlockList.cpp
@@ -7,4 +7,6 @@
#include <Swiften/Client/BlockList.h>
+#include <algorithm>
+
using namespace Swift;
@@ -12,2 +14,9 @@ BlockList::~BlockList() {
}
+
+bool BlockList::isBlocked(const JID& jid) const {
+ const std::vector<JID>& items = getItems();
+ return (std::find(items.begin(), items.end(), jid.toBare()) != items.end()) ||
+ (std::find(items.begin(), items.end(), JID(jid.getDomain())) != items.end()) ||
+ (std::find(items.begin(), items.end(), jid) != items.end());
+}
diff --git a/Swiften/Client/BlockList.h b/Swiften/Client/BlockList.h
index 39a211d..99c83c1 100644
--- a/Swiften/Client/BlockList.h
+++ b/Swiften/Client/BlockList.h
@@ -7,5 +7,5 @@
#pragma once
-#include <set>
+#include <vector>
#include <Swiften/JID/JID.h>
@@ -16,7 +16,8 @@ namespace Swift {
public:
enum State {
+ Init,
Requesting,
Available,
- Error,
+ Error
};
virtual ~BlockList();
@@ -24,5 +25,7 @@ namespace Swift {
virtual State getState() const = 0;
- virtual const std::set<JID>& getItems() const = 0;
+ virtual const std::vector<JID>& getItems() const = 0;
+
+ bool isBlocked(const JID& jid) const;
public:
diff --git a/Swiften/Client/BlockListImpl.cpp b/Swiften/Client/BlockListImpl.cpp
index dfaaaf1..5950233 100644
--- a/Swiften/Client/BlockListImpl.cpp
+++ b/Swiften/Client/BlockListImpl.cpp
@@ -9,16 +9,30 @@
#include <Swiften/Base/foreach.h>
+#include <algorithm>
+
using namespace Swift;
-BlockListImpl::BlockListImpl() {
+BlockListImpl::BlockListImpl() : state(Init) {
}
void BlockListImpl::setItems(const std::vector<JID>& items) {
- this->items = std::set<JID>(items.begin(), items.end());
+ foreach (const JID& jid, this->items) {
+ if (std::find(items.begin(), items.end(), jid) != items.end()) {
+ onItemRemoved(jid);
+ }
+ }
+
+ foreach (const JID& jid, items) {
+ if (std::find(this->items.begin(), this->items.end(), jid) != this->items.end()) {
+ onItemAdded(jid);
+ }
+ }
+ this->items = items;
}
void BlockListImpl::addItem(const JID& item) {
- if (items.insert(item).second) {
+ if (std::find(items.begin(), items.end(), item) == items.end()) {
+ items.push_back(item);
onItemAdded(item);
}
@@ -26,5 +40,7 @@ void BlockListImpl::addItem(const JID& item) {
void BlockListImpl::removeItem(const JID& item) {
- if (items.erase(item)) {
+ size_t oldSize = items.size();
+ items.erase(std::remove(items.begin(), items.end(), item), items.end());
+ if (items.size() != oldSize) {
onItemRemoved(item);
}
@@ -33,4 +49,5 @@ void BlockListImpl::removeItem(const JID& item) {
void BlockListImpl::setState(State state) {
if (this->state != state) {
+ this->state = state;
onStateChanged();
}
@@ -44,5 +61,6 @@ void BlockListImpl::addItems(const std::vector<JID>& items) {
void BlockListImpl::removeItems(const std::vector<JID>& items) {
- foreach (const JID& item, items) {
+ std::vector<JID> itemsToRemove = items;
+ foreach (const JID& item, itemsToRemove) {
removeItem(item);
}
@@ -50,7 +68,5 @@ void BlockListImpl::removeItems(const std::vector<JID>& items) {
void BlockListImpl::removeAllItems() {
- foreach (const JID& item, items) {
- removeItem(item);
- }
+ removeItems(items);
}
diff --git a/Swiften/Client/BlockListImpl.h b/Swiften/Client/BlockListImpl.h
index ef08340..2a799ae 100644
--- a/Swiften/Client/BlockListImpl.h
+++ b/Swiften/Client/BlockListImpl.h
@@ -20,5 +20,5 @@ namespace Swift {
void setState(State state);
- virtual const std::set<JID>& getItems() const {
+ virtual const std::vector<JID>& getItems() const {
return items;
}
@@ -33,5 +33,5 @@ namespace Swift {
private:
State state;
- std::set<JID> items;
+ std::vector<JID> items;
};
}
diff --git a/Swiften/Client/Client.cpp b/Swiften/Client/Client.cpp
index 4d3ee04..f158370 100644
--- a/Swiften/Client/Client.cpp
+++ b/Swiften/Client/Client.cpp
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2012 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -15,4 +15,5 @@
#include <Swiften/MUC/MUCRegistry.h>
#include <Swiften/MUC/MUCManager.h>
+#include <Swiften/PubSub/PubSubManagerImpl.h>
#include <Swiften/Client/MemoryStorages.h>
#include <Swiften/VCards/VCardManager.h>
@@ -30,4 +31,6 @@
#include <Swiften/Network/NetworkFactories.h>
#include <Swiften/FileTransfer/FileTransferManagerImpl.h>
+#include <Swiften/Whiteboard/WhiteboardSessionManager.h>
+#include <Swiften/Client/ClientBlockListManager.h>
#ifndef SWIFT_EXPERIMENTAL_FT
#include <Swiften/FileTransfer/UnitTest/DummyFileTransferManager.h>
@@ -37,5 +40,5 @@ namespace Swift {
Client::Client(const JID& jid, const SafeString& password, NetworkFactories* networkFactories, Storages* storages) : CoreClient(jid, password, networkFactories), storages(storages) {
- memoryStorages = new MemoryStorages();
+ memoryStorages = new MemoryStorages(networkFactories->getCryptoProvider());
softwareVersionResponder = new SoftwareVersionResponder(getIQRouter());
@@ -52,5 +55,5 @@ Client::Client(const JID& jid, const SafeString& password, NetworkFactories* net
stanzaChannelPresenceSender = new StanzaChannelPresenceSender(getStanzaChannel());
directedPresenceSender = new DirectedPresenceSender(stanzaChannelPresenceSender);
- discoManager = new ClientDiscoManager(getIQRouter(), directedPresenceSender);
+ discoManager = new ClientDiscoManager(getIQRouter(), directedPresenceSender, networkFactories->getCryptoProvider());
mucRegistry = new MUCRegistry();
@@ -58,6 +61,6 @@ Client::Client(const JID& jid, const SafeString& password, NetworkFactories* net
vcardManager = new VCardManager(jid, getIQRouter(), getStorages()->getVCardStorage());
- avatarManager = new AvatarManagerImpl(vcardManager, getStanzaChannel(), getStorages()->getAvatarStorage(), mucRegistry);
- capsManager = new CapsManager(getStorages()->getCapsStorage(), getStanzaChannel(), getIQRouter());
+ avatarManager = new AvatarManagerImpl(vcardManager, getStanzaChannel(), getStorages()->getAvatarStorage(), networkFactories->getCryptoProvider(), mucRegistry);
+ capsManager = new CapsManager(getStorages()->getCapsStorage(), getStanzaChannel(), getIQRouter(), networkFactories->getCryptoProvider());
entityCapsManager = new EntityCapsManager(capsManager, getStanzaChannel());
@@ -68,8 +71,19 @@ Client::Client(const JID& jid, const SafeString& password, NetworkFactories* net
jingleSessionManager = new JingleSessionManager(getIQRouter());
+ blockListManager = new ClientBlockListManager(getIQRouter());
fileTransferManager = NULL;
+
+ whiteboardSessionManager = NULL;
+#ifdef SWIFT_EXPERIMENTAL_WB
+ whiteboardSessionManager = new WhiteboardSessionManager(getIQRouter(), getStanzaChannel(), presenceOracle, getEntityCapsProvider());
+#endif
+
+ pubsubManager = new PubSubManagerImpl(getStanzaChannel(), getIQRouter());
}
Client::~Client() {
+ delete pubsubManager;
+ delete whiteboardSessionManager;
+
delete fileTransferManager;
delete jingleSessionManager;
@@ -113,5 +127,16 @@ void Client::setSoftwareVersion(const std::string& name, const std::string& vers
void Client::handleConnected() {
#ifdef SWIFT_EXPERIMENTAL_FT
- fileTransferManager = new FileTransferManagerImpl(getJID(), jingleSessionManager, getIQRouter(), getEntityCapsProvider(), presenceOracle, getNetworkFactories()->getConnectionFactory(), getNetworkFactories()->getConnectionServerFactory(), getNetworkFactories()->getTimerFactory(), getNetworkFactories()->getNATTraverser());
+ fileTransferManager = new FileTransferManagerImpl(
+ getJID(),
+ jingleSessionManager,
+ getIQRouter(),
+ getEntityCapsProvider(),
+ presenceOracle,
+ getNetworkFactories()->getConnectionFactory(),
+ getNetworkFactories()->getConnectionServerFactory(),
+ getNetworkFactories()->getTimerFactory(),
+ getNetworkFactories()->getNetworkEnvironment(),
+ getNetworkFactories()->getNATTraverser(),
+ getNetworkFactories()->getCryptoProvider());
#else
fileTransferManager = new DummyFileTransferManager();
@@ -165,3 +190,7 @@ FileTransferManager* Client::getFileTransferManager() const {
}
+WhiteboardSessionManager* Client::getWhiteboardSessionManager() const {
+ return whiteboardSessionManager;
+}
+
}
diff --git a/Swiften/Client/Client.h b/Swiften/Client/Client.h
index 940a526..9253074 100644
--- a/Swiften/Client/Client.h
+++ b/Swiften/Client/Client.h
@@ -7,6 +7,6 @@
#pragma once
+#include <Swiften/Base/API.h>
#include <Swiften/Client/CoreClient.h>
-
#include <Swiften/Base/SafeString.h>
@@ -37,4 +37,7 @@ namespace Swift {
class JingleSessionManager;
class FileTransferManager;
+ class WhiteboardSessionManager;
+ class ClientBlockListManager;
+ class PubSubManager;
/**
@@ -44,5 +47,5 @@ namespace Swift {
* performing most tasks on the XMPP network.
*/
- class Client : public CoreClient {
+ class SWIFTEN_API Client : public CoreClient {
public:
/**
@@ -136,4 +139,8 @@ namespace Swift {
}
+ ClientBlockListManager* getClientBlockListManager() const {
+ return blockListManager;
+ }
+
/**
* Returns a FileTransferManager for the client. This is only available after the onConnected
@@ -152,4 +159,11 @@ namespace Swift {
void setAlwaysTrustCertificates();
+ WhiteboardSessionManager* getWhiteboardSessionManager() const;
+
+ PubSubManager* getPubSubManager() const {
+ return pubsubManager;
+ }
+
+
public:
/**
@@ -186,4 +200,7 @@ namespace Swift {
FileTransferManager* fileTransferManager;
BlindCertificateTrustChecker* blindCertificateTrustChecker;
+ WhiteboardSessionManager* whiteboardSessionManager;
+ ClientBlockListManager* blockListManager;
+ PubSubManager* pubsubManager;
};
}
diff --git a/Swiften/Client/ClientBlockListManager.cpp b/Swiften/Client/ClientBlockListManager.cpp
index 7222cea..de43631 100644
--- a/Swiften/Client/ClientBlockListManager.cpp
+++ b/Swiften/Client/ClientBlockListManager.cpp
@@ -67,11 +67,11 @@ namespace {
ClientBlockListManager::ClientBlockListManager(IQRouter* iqRouter) : iqRouter(iqRouter) {
+
}
ClientBlockListManager::~ClientBlockListManager() {
+ if (blockList && blockList->getState() == BlockList::Available) {
unblockResponder->stop();
blockResponder->stop();
- if (getRequest) {
- getRequest->onResponse.disconnect(boost::bind(&ClientBlockListManager::handleBlockListReceived, this, _1, _2));
}
}
@@ -80,13 +80,43 @@ boost::shared_ptr<BlockList> ClientBlockListManager::getBlockList() {
if (!blockList) {
blockList = boost::make_shared<BlockListImpl>();
+ blockList->setState(BlockList::Init);
+ }
+ return blockList;
+}
+
+boost::shared_ptr<BlockList> ClientBlockListManager::requestBlockList() {
+ if (!blockList) {
+ blockList = boost::make_shared<BlockListImpl>();
+ }
blockList->setState(BlockList::Requesting);
- assert(!getRequest);
- getRequest = boost::make_shared< GenericRequest<BlockListPayload> >(IQ::Get, JID(), boost::make_shared<BlockListPayload>(), iqRouter);
+ boost::shared_ptr<GenericRequest<BlockListPayload> > getRequest = boost::make_shared< GenericRequest<BlockListPayload> >(IQ::Get, JID(), boost::make_shared<BlockListPayload>(), iqRouter);
getRequest->onResponse.connect(boost::bind(&ClientBlockListManager::handleBlockListReceived, this, _1, _2));
getRequest->send();
- }
return blockList;
}
+GenericRequest<BlockPayload>::ref ClientBlockListManager::createBlockJIDRequest(const JID& jid) {
+ return createBlockJIDsRequest(std::vector<JID>(1, jid));
+}
+
+GenericRequest<BlockPayload>::ref ClientBlockListManager::createBlockJIDsRequest(const std::vector<JID>& jids) {
+ boost::shared_ptr<BlockPayload> payload = boost::make_shared<BlockPayload>(jids);
+ return boost::make_shared< GenericRequest<BlockPayload> >(IQ::Set, JID(), payload, iqRouter);
+}
+
+GenericRequest<UnblockPayload>::ref ClientBlockListManager::createUnblockJIDRequest(const JID& jid) {
+ return createUnblockJIDsRequest(std::vector<JID>(1, jid));
+}
+
+GenericRequest<UnblockPayload>::ref ClientBlockListManager::createUnblockJIDsRequest(const std::vector<JID>& jids) {
+ boost::shared_ptr<UnblockPayload> payload = boost::make_shared<UnblockPayload>(jids);
+ return boost::make_shared< GenericRequest<UnblockPayload> >(IQ::Set, JID(), payload, iqRouter);
+}
+
+GenericRequest<UnblockPayload>::ref ClientBlockListManager::createUnblockAllRequest() {
+ return createUnblockJIDsRequest(std::vector<JID>());
+}
+
+
void ClientBlockListManager::handleBlockListReceived(boost::shared_ptr<BlockListPayload> payload, ErrorPayload::ref error) {
if (error || !payload) {
@@ -94,11 +124,15 @@ void ClientBlockListManager::handleBlockListReceived(boost::shared_ptr<BlockList
}
else {
- blockList->setState(BlockList::Available);
blockList->setItems(payload->getItems());
+ blockList->setState(BlockList::Available);
+ if (!blockResponder) {
blockResponder = boost::make_shared<BlockResponder>(blockList, iqRouter);
blockResponder->start();
+ }
+ if (!unblockResponder) {
unblockResponder = boost::make_shared<UnblockResponder>(blockList, iqRouter);
unblockResponder->start();
}
}
+}
diff --git a/Swiften/Client/ClientBlockListManager.h b/Swiften/Client/ClientBlockListManager.h
index 21d35e3..e715737 100644
--- a/Swiften/Client/ClientBlockListManager.h
+++ b/Swiften/Client/ClientBlockListManager.h
@@ -13,4 +13,5 @@
#include <Swiften/Elements/BlockListPayload.h>
#include <Swiften/Elements/UnblockPayload.h>
+#include <Swiften/Elements/DiscoInfo.h>
#include <Swiften/Queries/SetResponder.h>
#include <Swiften/Queries/GenericRequest.h>
@@ -26,6 +27,4 @@ namespace Swift {
~ClientBlockListManager();
- bool isSupported() const;
-
/**
* Returns the blocklist.
@@ -33,4 +32,16 @@ namespace Swift {
boost::shared_ptr<BlockList> getBlockList();
+ /**
+ * Get the blocklist from the server.
+ */
+ boost::shared_ptr<BlockList> requestBlockList();
+
+ GenericRequest<BlockPayload>::ref createBlockJIDRequest(const JID& jid);
+ GenericRequest<BlockPayload>::ref createBlockJIDsRequest(const std::vector<JID>& jids);
+
+ GenericRequest<UnblockPayload>::ref createUnblockJIDRequest(const JID& jid);
+ GenericRequest<UnblockPayload>::ref createUnblockJIDsRequest(const std::vector<JID>& jids);
+ GenericRequest<UnblockPayload>::ref createUnblockAllRequest();
+
private:
void handleBlockListReceived(boost::shared_ptr<BlockListPayload> payload, ErrorPayload::ref);
@@ -38,5 +49,4 @@ namespace Swift {
private:
IQRouter* iqRouter;
- boost::shared_ptr<GenericRequest<BlockListPayload> > getRequest;
boost::shared_ptr<SetResponder<BlockPayload> > blockResponder;
boost::shared_ptr<SetResponder<UnblockPayload> > unblockResponder;
diff --git a/Swiften/Client/ClientOptions.h b/Swiften/Client/ClientOptions.h
index fbec272..e5fcda9 100644
--- a/Swiften/Client/ClientOptions.h
+++ b/Swiften/Client/ClientOptions.h
@@ -18,5 +18,25 @@ namespace Swift {
};
- ClientOptions() : useStreamCompression(true), useTLS(UseTLSWhenAvailable), allowPLAINWithoutTLS(false), useStreamResumption(false), forgetPassword(false), useAcks(true), boshHTTPConnectProxyAuthID(""), boshHTTPConnectProxyAuthPassword("") {
+ enum ProxyType {
+ NoProxy,
+ SystemConfiguredProxy,
+ SOCKS5Proxy,
+ HTTPConnectProxy
+ };
+
+ ClientOptions() :
+ useStreamCompression(true),
+ useTLS(UseTLSWhenAvailable),
+ allowPLAINWithoutTLS(false),
+ useStreamResumption(false),
+ forgetPassword(false),
+ useAcks(true),
+ manualHostname(""),
+ manualPort(-1),
+ proxyType(SystemConfiguredProxy),
+ manualProxyHostname(""),
+ manualProxyPort(-1),
+ boshHTTPConnectProxyAuthID(""),
+ boshHTTPConnectProxyAuthPassword("") {
}
@@ -67,4 +87,33 @@ namespace Swift {
/**
+ * The hostname to connect to.
+ * Leave this empty for standard XMPP connection, based on the JID domain.
+ */
+ std::string manualHostname;
+
+ /**
+ * The port to connect to.
+ * Leave this to -1 to use the port discovered by SRV lookups, and 5222 as a
+ * fallback.
+ */
+ int manualPort;
+
+ /**
+ * The type of proxy to use for connecting to the XMPP
+ * server.
+ */
+ ProxyType proxyType;
+
+ /**
+ * Override the system-configured proxy hostname.
+ */
+ std::string manualProxyHostname;
+
+ /**
+ * Override the system-configured proxy port.
+ */
+ int manualProxyPort;
+
+ /**
* If non-empty, use BOSH instead of direct TCP, with the given URL.
* Default: empty (no BOSH)
diff --git a/Swiften/Client/ClientSession.cpp b/Swiften/Client/ClientSession.cpp
index 70f0398..500299a 100644
--- a/Swiften/Client/ClientSession.cpp
+++ b/Swiften/Client/ClientSession.cpp
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2014 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -38,6 +38,8 @@
#include <Swiften/Elements/ResourceBind.h>
#include <Swiften/SASL/PLAINClientAuthenticator.h>
+#include <Swiften/SASL/EXTERNALClientAuthenticator.h>
#include <Swiften/SASL/SCRAMSHA1ClientAuthenticator.h>
#include <Swiften/SASL/DIGESTMD5ClientAuthenticator.h>
+#include <Swiften/Crypto/CryptoProvider.h>
#include <Swiften/Session/SessionStream.h>
#include <Swiften/TLS/CertificateTrustChecker.h>
@@ -48,12 +50,19 @@
#endif
+#define CHECK_STATE_OR_RETURN(a) \
+ if (!checkState(a)) { return; }
+
namespace Swift {
ClientSession::ClientSession(
const JID& jid,
- boost::shared_ptr<SessionStream> stream) :
+ boost::shared_ptr<SessionStream> stream,
+ IDNConverter* idnConverter,
+ CryptoProvider* crypto) :
localJID(jid),
state(Initial),
stream(stream),
+ idnConverter(idnConverter),
+ crypto(crypto),
allowPLAINOverNonTLS(false),
useStreamCompression(true),
@@ -101,9 +110,9 @@ void ClientSession::sendStanza(boost::shared_ptr<Stanza> stanza) {
void ClientSession::handleStreamStart(const ProtocolHeader&) {
- checkState(WaitingForStreamStart);
+ CHECK_STATE_OR_RETURN(WaitingForStreamStart);
state = Negotiating;
}
-void ClientSession::handleElement(boost::shared_ptr<Element> element) {
+void ClientSession::handleElement(boost::shared_ptr<ToplevelElement> element) {
if (boost::shared_ptr<Stanza> stanza = boost::dynamic_pointer_cast<Stanza>(element)) {
if (stanzaAckResponder_) {
@@ -162,9 +171,9 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) {
}
else {
- std::cerr << "Warning: Got invalid ack from server" << std::endl;
+ SWIFT_LOG(warning) << "Got invalid ack from server";
}
}
else {
- std::cerr << "Warning: Ignoring ack" << std::endl;
+ SWIFT_LOG(warning) << "Ignoring ack";
}
}
@@ -182,7 +191,5 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) {
}
else if (StreamFeatures* streamFeatures = dynamic_cast<StreamFeatures*>(element.get())) {
- if (!checkState(Negotiating)) {
- return;
- }
+ CHECK_STATE_OR_RETURN(Negotiating);
if (streamFeatures->hasStartTLS() && stream->supportsTLSEncryption() && useTLS != NeverUseTLS) {
@@ -200,4 +207,5 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) {
if (stream->hasTLSCertificate()) {
if (streamFeatures->hasAuthenticationMechanism("EXTERNAL")) {
+ authenticator = new EXTERNALClientAuthenticator();
state = Authenticating;
stream->writeElement(boost::make_shared<AuthRequest>("EXTERNAL", createSafeByteArray("")));
@@ -208,4 +216,5 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) {
}
else if (streamFeatures->hasAuthenticationMechanism("EXTERNAL")) {
+ authenticator = new EXTERNALClientAuthenticator();
state = Authenticating;
stream->writeElement(boost::make_shared<AuthRequest>("EXTERNAL", createSafeByteArray("")));
@@ -214,12 +223,12 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) {
std::ostringstream s;
ByteArray finishMessage;
- bool plus = stream->isTLSEncrypted() && streamFeatures->hasAuthenticationMechanism("SCRAM-SHA-1-PLUS");
- if (plus) {
+ bool plus = streamFeatures->hasAuthenticationMechanism("SCRAM-SHA-1-PLUS");
+ if (stream->isTLSEncrypted()) {
finishMessage = stream->getTLSFinishMessage();
plus &= !finishMessage.empty();
}
s << boost::uuids::random_generator()();
- SCRAMSHA1ClientAuthenticator* scramAuthenticator = new SCRAMSHA1ClientAuthenticator(s.str(), plus);
- if (plus) {
+ SCRAMSHA1ClientAuthenticator* scramAuthenticator = new SCRAMSHA1ClientAuthenticator(s.str(), plus, idnConverter, crypto);
+ if (!finishMessage.empty()) {
scramAuthenticator->setTLSChannelBindingData(finishMessage);
}
@@ -233,9 +242,9 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) {
onNeedCredentials();
}
- else if (streamFeatures->hasAuthenticationMechanism("DIGEST-MD5") && DIGESTMD5ClientAuthenticator::canBeUsed()) {
+ else if (streamFeatures->hasAuthenticationMechanism("DIGEST-MD5") && crypto->isMD5AllowedForCrypto()) {
std::ostringstream s;
s << boost::uuids::random_generator()();
// FIXME: Host should probably be the actual host
- authenticator = new DIGESTMD5ClientAuthenticator(localJID.getDomain(), s.str());
+ authenticator = new DIGESTMD5ClientAuthenticator(localJID.getDomain(), s.str(), crypto);
state = WaitingForCredentials;
onNeedCredentials();
@@ -262,5 +271,5 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) {
}
else if (boost::dynamic_pointer_cast<Compressed>(element)) {
- checkState(Compressing);
+ CHECK_STATE_OR_RETURN(Compressing);
state = WaitingForStreamStart;
stream->addZLibCompression();
@@ -285,5 +294,5 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) {
}
else if (AuthChallenge* challenge = dynamic_cast<AuthChallenge*>(element.get())) {
- checkState(Authenticating);
+ CHECK_STATE_OR_RETURN(Authenticating);
assert(authenticator);
if (authenticator->setChallenge(challenge->getValue())) {
@@ -295,8 +304,7 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) {
}
else if (AuthSuccess* authSuccess = dynamic_cast<AuthSuccess*>(element.get())) {
- checkState(Authenticating);
- if (authenticator && !authenticator->setChallenge(authSuccess->getValue())) {
- delete authenticator;
- authenticator = NULL;
+ CHECK_STATE_OR_RETURN(Authenticating);
+ assert(authenticator);
+ if (!authenticator->setChallenge(authSuccess->getValue())) {
finishSession(Error::ServerVerificationFailedError);
}
@@ -310,10 +318,8 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) {
}
else if (dynamic_cast<AuthFailure*>(element.get())) {
- delete authenticator;
- authenticator = NULL;
finishSession(Error::AuthenticationFailedError);
}
else if (dynamic_cast<TLSProceed*>(element.get())) {
- checkState(WaitingForEncrypt);
+ CHECK_STATE_OR_RETURN(WaitingForEncrypt);
state = Encrypting;
stream->addTLSEncryption();
@@ -362,4 +368,5 @@ bool ClientSession::checkState(State state) {
void ClientSession::sendCredentials(const SafeByteArray& password) {
assert(WaitingForCredentials);
+ assert(authenticator);
state = Authenticating;
authenticator->setCredentials(localJID.getNode(), password);
@@ -368,24 +375,24 @@ void ClientSession::sendCredentials(const SafeByteArray& password) {
void ClientSession::handleTLSEncrypted() {
- checkState(Encrypting);
+ CHECK_STATE_OR_RETURN(Encrypting);
- Certificate::ref certificate = stream->getPeerCertificate();
+ std::vector<Certificate::ref> certificateChain = stream->getPeerCertificateChain();
boost::shared_ptr<CertificateVerificationError> verificationError = stream->getPeerCertificateVerificationError();
if (verificationError) {
- checkTrustOrFinish(certificate, verificationError);
+ checkTrustOrFinish(certificateChain, verificationError);
}
else {
- ServerIdentityVerifier identityVerifier(localJID);
- if (identityVerifier.certificateVerifies(certificate)) {
+ ServerIdentityVerifier identityVerifier(localJID, idnConverter);
+ if (!certificateChain.empty() && identityVerifier.certificateVerifies(certificateChain[0])) {
continueAfterTLSEncrypted();
}
else {
- checkTrustOrFinish(certificate, boost::make_shared<CertificateVerificationError>(CertificateVerificationError::InvalidServerIdentity));
+ checkTrustOrFinish(certificateChain, boost::make_shared<CertificateVerificationError>(CertificateVerificationError::InvalidServerIdentity));
}
}
}
-void ClientSession::checkTrustOrFinish(Certificate::ref certificate, boost::shared_ptr<CertificateVerificationError> error) {
- if (certificateTrustChecker && certificateTrustChecker->isCertificateTrusted(certificate)) {
+void ClientSession::checkTrustOrFinish(const std::vector<Certificate::ref>& certificateChain, boost::shared_ptr<CertificateVerificationError> error) {
+ if (certificateTrustChecker && certificateTrustChecker->isCertificateTrusted(certificateChain)) {
continueAfterTLSEncrypted();
}
@@ -441,8 +448,15 @@ void ClientSession::finishSession(boost::shared_ptr<Swift::Error> error) {
error_ = error;
}
+ else {
+ SWIFT_LOG(warning) << "Session finished twice";
+ }
assert(stream->isOpen());
if (stanzaAckResponder_) {
stanzaAckResponder_->handleAckRequestReceived();
}
+ if (authenticator) {
+ delete authenticator;
+ authenticator = NULL;
+ }
stream->writeFooter();
stream->close();
diff --git a/Swiften/Client/ClientSession.h b/Swiften/Client/ClientSession.h
index 2205c8d..8a3deb4 100644
--- a/Swiften/Client/ClientSession.h
+++ b/Swiften/Client/ClientSession.h
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2014 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -11,9 +11,10 @@
#include <boost/enable_shared_from_this.hpp>
+#include <Swiften/Base/API.h>
#include <Swiften/Base/Error.h>
#include <Swiften/Session/SessionStream.h>
#include <string>
#include <Swiften/JID/JID.h>
-#include <Swiften/Elements/Element.h>
+#include <Swiften/Elements/ToplevelElement.h>
#include <Swiften/StreamManagement/StanzaAckRequester.h>
#include <Swiften/StreamManagement/StanzaAckResponder.h>
@@ -22,6 +23,8 @@ namespace Swift {
class ClientAuthenticator;
class CertificateTrustChecker;
+ class IDNConverter;
+ class CryptoProvider;
- class ClientSession : public boost::enable_shared_from_this<ClientSession> {
+ class SWIFTEN_API ClientSession : public boost::enable_shared_from_this<ClientSession> {
public:
enum State {
@@ -53,5 +56,5 @@ namespace Swift {
TLSClientCertificateError,
TLSError,
- StreamError,
+ StreamError
} type;
Error(Type type) : type(type) {}
@@ -66,6 +69,6 @@ namespace Swift {
~ClientSession();
- static boost::shared_ptr<ClientSession> create(const JID& jid, boost::shared_ptr<SessionStream> stream) {
- return boost::shared_ptr<ClientSession>(new ClientSession(jid, stream));
+ static boost::shared_ptr<ClientSession> create(const JID& jid, boost::shared_ptr<SessionStream> stream, IDNConverter* idnConverter, CryptoProvider* crypto) {
+ return boost::shared_ptr<ClientSession>(new ClientSession(jid, stream, idnConverter, crypto));
}
@@ -92,5 +95,7 @@ namespace Swift {
bool getStreamManagementEnabled() const {
- return stanzaAckRequester_;
+ // Explicitly convert to bool. In C++11, it would be cleaner to
+ // compare to nullptr.
+ return static_cast<bool>(stanzaAckRequester_);
}
@@ -99,4 +104,8 @@ namespace Swift {
}
+ std::vector<Certificate::ref> getPeerCertificateChain() const {
+ return stream->getPeerCertificateChain();
+ }
+
const JID& getLocalJID() const {
return localJID;
@@ -127,5 +136,7 @@ namespace Swift {
ClientSession(
const JID& jid,
- boost::shared_ptr<SessionStream>);
+ boost::shared_ptr<SessionStream>,
+ IDNConverter* idnConverter,
+ CryptoProvider* crypto);
void finishSession(Error::Type error);
@@ -138,5 +149,5 @@ namespace Swift {
void sendStreamHeader();
- void handleElement(boost::shared_ptr<Element>);
+ void handleElement(boost::shared_ptr<ToplevelElement>);
void handleStreamStart(const ProtocolHeader&);
void handleStreamClosed(boost::shared_ptr<Swift::Error>);
@@ -151,5 +162,5 @@ namespace Swift {
void ack(unsigned int handledStanzasCount);
void continueAfterTLSEncrypted();
- void checkTrustOrFinish(Certificate::ref certificate, boost::shared_ptr<CertificateVerificationError> error);
+ void checkTrustOrFinish(const std::vector<Certificate::ref>& certificateChain, boost::shared_ptr<CertificateVerificationError> error);
private:
@@ -157,4 +168,6 @@ namespace Swift {
State state;
boost::shared_ptr<SessionStream> stream;
+ IDNConverter* idnConverter;
+ CryptoProvider* crypto;
bool allowPLAINOverNonTLS;
bool useStreamCompression;
diff --git a/Swiften/Client/ClientSessionStanzaChannel.cpp b/Swiften/Client/ClientSessionStanzaChannel.cpp
index 5dc0a42..8d85953 100644
--- a/Swiften/Client/ClientSessionStanzaChannel.cpp
+++ b/Swiften/Client/ClientSessionStanzaChannel.cpp
@@ -83,4 +83,11 @@ bool ClientSessionStanzaChannel::getStreamManagementEnabled() const {
}
+std::vector<Certificate::ref> ClientSessionStanzaChannel::getPeerCertificateChain() const {
+ if (session) {
+ return session->getPeerCertificateChain();
+ }
+ return std::vector<Certificate::ref>();
+}
+
void ClientSessionStanzaChannel::handleStanzaAcked(boost::shared_ptr<Stanza> stanza) {
onStanzaAcked(stanza);
diff --git a/Swiften/Client/ClientSessionStanzaChannel.h b/Swiften/Client/ClientSessionStanzaChannel.h
index 47fb50e..2743a16 100644
--- a/Swiften/Client/ClientSessionStanzaChannel.h
+++ b/Swiften/Client/ClientSessionStanzaChannel.h
@@ -28,4 +28,5 @@ namespace Swift {
void sendPresence(boost::shared_ptr<Presence> presence);
bool getStreamManagementEnabled() const;
+ virtual std::vector<Certificate::ref> getPeerCertificateChain() const;
bool isAvailable() const {
diff --git a/Swiften/Client/ClientXMLTracer.cpp b/Swiften/Client/ClientXMLTracer.cpp
index 405e3d1..9bfa047 100644
--- a/Swiften/Client/ClientXMLTracer.cpp
+++ b/Swiften/Client/ClientXMLTracer.cpp
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2014 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -10,10 +10,16 @@
#include <boost/bind.hpp>
+#include <Swiften/Base/Platform.h>
+
namespace Swift {
ClientXMLTracer::ClientXMLTracer(CoreClient* client, bool bosh) : bosh(bosh) {
+#ifdef SWIFTEN_PLATFORM_WIN32
+ beautifier = new XMLBeautifier(true, false);
+#else
beautifier = new XMLBeautifier(true, true);
- client->onDataRead.connect(boost::bind(&ClientXMLTracer::printData, this, '<', _1));
- client->onDataWritten.connect(boost::bind(&ClientXMLTracer::printData, this, '>', _1));
+#endif
+ onDataReadConnection = client->onDataRead.connect(boost::bind(&ClientXMLTracer::printData, this, '<', _1));
+ onDataWrittenConnection = client->onDataWritten.connect(boost::bind(&ClientXMLTracer::printData, this, '>', _1));
}
@@ -26,12 +32,12 @@ void ClientXMLTracer::printData(char direction, const SafeByteArray& data) {
if (bosh) {
std::string line = byteArrayToString(ByteArray(data.begin(), data.end()));
- size_t endOfHTTP = line.find("\r\n\r\n");
- if (false && endOfHTTP != std::string::npos) {
- /* Disabled because it swallows bits of XML (namespaces, if I recall) */
- std::cerr << line.substr(0, endOfHTTP) << std::endl << beautifier->beautify(line.substr(endOfHTTP)) << std::endl;
- }
- else {
+// Disabled because it swallows bits of XML (namespaces, if I recall)
+// size_t endOfHTTP = line.find("\r\n\r\n");
+// if (false && endOfHTTP != std::string::npos) {
+// std::cerr << line.substr(0, endOfHTTP) << std::endl << beautifier->beautify(line.substr(endOfHTTP)) << std::endl;
+// }
+// else {
std::cerr << line << std::endl;
- }
+// }
}
else {
diff --git a/Swiften/Client/ClientXMLTracer.h b/Swiften/Client/ClientXMLTracer.h
index 67040c4..95e2f6f 100644
--- a/Swiften/Client/ClientXMLTracer.h
+++ b/Swiften/Client/ClientXMLTracer.h
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2014 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -7,4 +7,5 @@
#pragma once
+#include <Swiften/Base/API.h>
#include <Swiften/Client/CoreClient.h>
#include <Swiften/Client/XMLBeautifier.h>
@@ -12,8 +13,9 @@
namespace Swift {
- class ClientXMLTracer {
+ class SWIFTEN_API ClientXMLTracer {
public:
ClientXMLTracer(CoreClient* client, bool bosh = false);
~ClientXMLTracer();
+
private:
void printData(char direction, const SafeByteArray& data);
@@ -23,4 +25,6 @@ namespace Swift {
XMLBeautifier *beautifier;
bool bosh;
+ boost::bsignals::scoped_connection onDataReadConnection;
+ boost::bsignals::scoped_connection onDataWrittenConnection;
};
}
diff --git a/Swiften/Client/CoreClient.cpp b/Swiften/Client/CoreClient.cpp
index 8a922ba..da755b1 100644
--- a/Swiften/Client/CoreClient.cpp
+++ b/Swiften/Client/CoreClient.cpp
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010-2011 Remko Tronçon
+ * Copyright (c) 2010-2014 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -8,4 +8,5 @@
#include <boost/bind.hpp>
+#include <boost/optional.hpp>
#include <boost/smart_ptr/make_shared.hpp>
@@ -54,28 +55,68 @@ CoreClient::~CoreClient() {
void CoreClient::connect(const ClientOptions& o) {
- SWIFT_LOG(debug) << "Connecting" << std::endl;
- options = o;
- connect(jid_.getDomain());
-}
+ SWIFT_LOG(debug) << "Connecting ";
-void CoreClient::connect(const std::string& host) {
forceReset();
-
- SWIFT_LOG(debug) << "Connecting to host " << host << std::endl;
disconnectRequested_ = false;
- assert(!connector_);
+
+ options = o;
+
+
+ // Determine connection types to use
assert(proxyConnectionFactories.empty());
- if (networkFactories->getProxyProvider()->getSOCKS5Proxy().isValid()) {
- proxyConnectionFactories.push_back(new SOCKS5ProxiedConnectionFactory(networkFactories->getConnectionFactory(), networkFactories->getProxyProvider()->getSOCKS5Proxy()));
+ bool useDirectConnection = true;
+ HostAddressPort systemSOCKS5Proxy = networkFactories->getProxyProvider()->getSOCKS5Proxy();
+ HostAddressPort systemHTTPConnectProxy = networkFactories->getProxyProvider()->getHTTPConnectProxy();
+ switch (o.proxyType) {
+ case ClientOptions::NoProxy:
+ SWIFT_LOG(debug) << " without a proxy" << std::endl;
+ break;
+ case ClientOptions::SystemConfiguredProxy:
+ SWIFT_LOG(debug) << " with a system configured proxy" << std::endl;
+ if (systemSOCKS5Proxy.isValid()) {
+ SWIFT_LOG(debug) << "Found SOCK5 Proxy: " << systemSOCKS5Proxy.getAddress().toString() << ":" << systemSOCKS5Proxy.getPort() << std::endl;
+ proxyConnectionFactories.push_back(new SOCKS5ProxiedConnectionFactory(networkFactories->getDomainNameResolver(), networkFactories->getConnectionFactory(), networkFactories->getTimerFactory(), systemSOCKS5Proxy.getAddress().toString(), systemSOCKS5Proxy.getPort()));
+ }
+ if (systemHTTPConnectProxy.isValid()) {
+ SWIFT_LOG(debug) << "Found HTTPConnect Proxy: " << systemHTTPConnectProxy.getAddress().toString() << ":" << systemHTTPConnectProxy.getPort() << std::endl;
+ proxyConnectionFactories.push_back(new HTTPConnectProxiedConnectionFactory(networkFactories->getDomainNameResolver(), networkFactories->getConnectionFactory(), networkFactories->getTimerFactory(), systemHTTPConnectProxy.getAddress().toString(), systemHTTPConnectProxy.getPort()));
+ }
+ break;
+ case ClientOptions::SOCKS5Proxy: {
+ SWIFT_LOG(debug) << " with manual configured SOCKS5 proxy" << std::endl;
+ std::string proxyHostname = o.manualProxyHostname.empty() ? systemSOCKS5Proxy.getAddress().toString() : o.manualProxyHostname;
+ int proxyPort = o.manualProxyPort == -1 ? systemSOCKS5Proxy.getPort() : o.manualProxyPort;
+ SWIFT_LOG(debug) << "Proxy: " << proxyHostname << ":" << proxyPort << std::endl;
+ proxyConnectionFactories.push_back(new SOCKS5ProxiedConnectionFactory(networkFactories->getDomainNameResolver(), networkFactories->getConnectionFactory(), networkFactories->getTimerFactory(), proxyHostname, proxyPort));
+ useDirectConnection = false;
+ break;
+ }
+ case ClientOptions::HTTPConnectProxy: {
+ SWIFT_LOG(debug) << " with manual configured HTTPConnect proxy" << std::endl;
+ std::string proxyHostname = o.manualProxyHostname.empty() ? systemHTTPConnectProxy.getAddress().toString() : o.manualProxyHostname;
+ int proxyPort = o.manualProxyPort == -1 ? systemHTTPConnectProxy.getPort() : o.manualProxyPort;
+ SWIFT_LOG(debug) << "Proxy: " << proxyHostname << ":" << proxyPort << std::endl;
+ proxyConnectionFactories.push_back(new HTTPConnectProxiedConnectionFactory(networkFactories->getDomainNameResolver(), networkFactories->getConnectionFactory(), networkFactories->getTimerFactory(), proxyHostname, proxyPort));
+ useDirectConnection = false;
+ break;
}
- if(networkFactories->getProxyProvider()->getHTTPConnectProxy().isValid()) {
- proxyConnectionFactories.push_back(new HTTPConnectProxiedConnectionFactory(networkFactories->getDomainNameResolver(), networkFactories->getConnectionFactory(), networkFactories->getTimerFactory(), networkFactories->getEventLoop(), networkFactories->getProxyProvider()->getHTTPConnectProxy().getAddress().toString(), networkFactories->getProxyProvider()->getHTTPConnectProxy().getPort()));
}
std::vector<ConnectionFactory*> connectionFactories(proxyConnectionFactories);
- if (options.boshURL.empty()) {
+ if (useDirectConnection) {
connectionFactories.push_back(networkFactories->getConnectionFactory());
- connector_ = boost::make_shared<ChainedConnector>(host, networkFactories->getDomainNameResolver(), connectionFactories, networkFactories->getTimerFactory());
+ }
+
+ // Create connector
+ std::string host = o.manualHostname.empty() ? jid_.getDomain() : o.manualHostname;
+ int port = o.manualPort;
+ boost::optional<std::string> serviceLookupPrefix;
+ if (o.manualHostname.empty()) {
+ serviceLookupPrefix = "_xmpp-client._tcp.";
+ }
+ assert(!connector_);
+ if (options.boshURL.isEmpty()) {
+ connector_ = boost::make_shared<ChainedConnector>(host, port, serviceLookupPrefix, networkFactories->getDomainNameResolver(), connectionFactories, networkFactories->getTimerFactory());
connector_->onConnectFinished.connect(boost::bind(&CoreClient::handleConnectorFinished, this, _1, _2));
- connector_->setTimeoutMilliseconds(60*1000);
+ connector_->setTimeoutMilliseconds(2*60*1000);
connector_->start();
}
@@ -107,5 +148,5 @@ void CoreClient::connect(const std::string& host) {
void CoreClient::bindSessionToStream() {
- session_ = ClientSession::create(jid_, sessionStream_);
+ session_ = ClientSession::create(jid_, sessionStream_, networkFactories->getIDNConverter(), networkFactories->getCryptoProvider());
session_->setCertificateTrustChecker(certificateTrustChecker);
session_->setUseStreamCompression(options.useStreamCompression);
@@ -361,4 +402,8 @@ bool CoreClient::getStreamManagementEnabled() const {
}
+bool CoreClient::isStreamEncrypted() const {
+ return sessionStream_->isTLSEncrypted();
+}
+
StanzaChannel* CoreClient::getStanzaChannel() const {
return stanzaChannel_;
@@ -406,9 +451,9 @@ void CoreClient::resetSession() {
void CoreClient::forceReset() {
if (connector_) {
- std::cerr << "Warning: Client not disconnected properly: Connector still active" << std::endl;
+ SWIFT_LOG(warning) << "Client not disconnected properly: Connector still active" << std::endl;
resetConnector();
}
if (sessionStream_ || connection_) {
- std::cerr << "Warning: Client not disconnected properly: Session still active" << std::endl;
+ SWIFT_LOG(warning) << "Client not disconnected properly: Session still active" << std::endl;
resetSession();
}
diff --git a/Swiften/Client/CoreClient.h b/Swiften/Client/CoreClient.h
index cafc634..eadfd9d 100644
--- a/Swiften/Client/CoreClient.h
+++ b/Swiften/Client/CoreClient.h
@@ -9,6 +9,7 @@
#include <string>
#include <boost/shared_ptr.hpp>
-#include <Swiften/Base/boost_bsignals.h>
+#include <Swiften/Base/API.h>
+#include <Swiften/Base/boost_bsignals.h>
#include <Swiften/Entity/Entity.h>
#include <Swiften/JID/JID.h>
@@ -46,9 +47,8 @@ namespace Swift {
* for most needs.
*/
- class CoreClient : public Entity {
+ class SWIFTEN_API CoreClient : public Entity {
public:
/**
* Constructs a client for the given JID with the given password.
- * The given eventLoop will be used to post events to.
*/
CoreClient(const JID& jid, const SafeByteArray& password, NetworkFactories* networkFactories);
@@ -75,6 +75,4 @@ namespace Swift {
void disconnect();
- void connect(const std::string& host);
-
/**
* Sends a message.
@@ -128,4 +126,9 @@ namespace Swift {
bool getStreamManagementEnabled() const;
+ /**
+ * Checks whether stream encryption (TLS) is currently active.
+ */
+ bool isStreamEncrypted() const;
+
StanzaChannel* getStanzaChannel() const;
@@ -201,5 +204,5 @@ namespace Swift {
* Called before onConnected signal is emmitted.
*/
- virtual void handleConnected() {};
+ virtual void handleConnected() {}
private:
diff --git a/Swiften/Client/DummyStanzaChannel.h b/Swiften/Client/DummyStanzaChannel.h
index c2f3919..5cdedba 100644
--- a/Swiften/Client/DummyStanzaChannel.h
+++ b/Swiften/Client/DummyStanzaChannel.h
@@ -80,4 +80,8 @@ namespace Swift {
}
+ std::vector<Certificate::ref> getPeerCertificateChain() const {
+ return std::vector<Certificate::ref>();
+ }
+
std::vector<boost::shared_ptr<Stanza> > sentStanzas;
bool available_;
diff --git a/Swiften/Client/MemoryStorages.cpp b/Swiften/Client/MemoryStorages.cpp
index fe171f7..850c1b2 100644
--- a/Swiften/Client/MemoryStorages.cpp
+++ b/Swiften/Client/MemoryStorages.cpp
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2013 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -10,12 +10,18 @@
#include <Swiften/Disco/CapsMemoryStorage.h>
#include <Swiften/Roster/RosterMemoryStorage.h>
+#include <Swiften/History/SQLiteHistoryStorage.h>
namespace Swift {
-MemoryStorages::MemoryStorages() {
- vcardStorage = new VCardMemoryStorage();
+MemoryStorages::MemoryStorages(CryptoProvider* crypto) {
+ vcardStorage = new VCardMemoryStorage(crypto);
capsStorage = new CapsMemoryStorage();
avatarStorage = new AvatarMemoryStorage();
rosterStorage = new RosterMemoryStorage();
+#ifdef SWIFT_EXPERIMENTAL_HISTORY
+ historyStorage = new SQLiteHistoryStorage(":memory:");
+#else
+ historyStorage = NULL;
+#endif
}
@@ -25,4 +31,5 @@ MemoryStorages::~MemoryStorages() {
delete capsStorage;
delete vcardStorage;
+ delete historyStorage;
}
@@ -43,4 +50,12 @@ RosterStorage* MemoryStorages::getRosterStorage() const {
}
+HistoryStorage* MemoryStorages::getHistoryStorage() const {
+#ifdef SWIFT_EXPERIMENTAL_HISTORY
+ return historyStorage;
+#else
+ return NULL;
+#endif
+}
+
}
diff --git a/Swiften/Client/MemoryStorages.h b/Swiften/Client/MemoryStorages.h
index ca01a7a..68ec285 100644
--- a/Swiften/Client/MemoryStorages.h
+++ b/Swiften/Client/MemoryStorages.h
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2013 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -11,4 +11,5 @@
namespace Swift {
class VCardMemoryStorage;
+ class CryptoProvider;
/**
@@ -18,5 +19,5 @@ namespace Swift {
class MemoryStorages : public Storages {
public:
- MemoryStorages();
+ MemoryStorages(CryptoProvider*);
~MemoryStorages();
@@ -25,4 +26,5 @@ namespace Swift {
virtual CapsStorage* getCapsStorage() const;
virtual RosterStorage* getRosterStorage() const;
+ virtual HistoryStorage* getHistoryStorage() const;
private:
@@ -31,4 +33,5 @@ namespace Swift {
CapsStorage* capsStorage;
RosterStorage* rosterStorage;
+ HistoryStorage* historyStorage;
};
}
diff --git a/Swiften/Client/NickManager.h b/Swiften/Client/NickManager.h
index 288aa7b..c5a452e 100644
--- a/Swiften/Client/NickManager.h
+++ b/Swiften/Client/NickManager.h
@@ -7,9 +7,10 @@
#pragma once
+#include <Swiften/Base/API.h>
#include <Swiften/Base/boost_bsignals.h>
#include <string>
namespace Swift {
- class NickManager {
+ class SWIFTEN_API NickManager {
public:
virtual ~NickManager();
diff --git a/Swiften/Client/NickResolver.h b/Swiften/Client/NickResolver.h
index 584f2ce..306703e 100644
--- a/Swiften/Client/NickResolver.h
+++ b/Swiften/Client/NickResolver.h
@@ -7,7 +7,8 @@
#include <map>
#include <boost/shared_ptr.hpp>
+#include <string>
+#include <Swiften/Base/API.h>
#include <Swiften/Base/boost_bsignals.h>
-#include <string>
#include <Swiften/JID/JID.h>
#include <Swiften/Elements/VCard.h>
@@ -17,5 +18,6 @@ namespace Swift {
class MUCRegistry;
class VCardManager;
- class NickResolver {
+
+ class SWIFTEN_API NickResolver {
public:
NickResolver(const JID& ownJID, XMPPRoster* xmppRoster, VCardManager* vcardManager, MUCRegistry* mucRegistry);
diff --git a/Swiften/Client/StanzaChannel.h b/Swiften/Client/StanzaChannel.h
index f1d76e0..5e85d3c 100644
--- a/Swiften/Client/StanzaChannel.h
+++ b/Swiften/Client/StanzaChannel.h
@@ -13,4 +13,5 @@
#include <Swiften/Elements/Message.h>
#include <Swiften/Elements/Presence.h>
+#include <Swiften/TLS/Certificate.h>
namespace Swift {
@@ -21,4 +22,5 @@ namespace Swift {
virtual bool isAvailable() const = 0;
virtual bool getStreamManagementEnabled() const = 0;
+ virtual std::vector<Certificate::ref> getPeerCertificateChain() const = 0;
boost::signal<void (bool /* isAvailable */)> onAvailableChanged;
diff --git a/Swiften/Client/Storages.h b/Swiften/Client/Storages.h
index 1c5bbe9..76650a6 100644
--- a/Swiften/Client/Storages.h
+++ b/Swiften/Client/Storages.h
@@ -7,4 +7,6 @@
#pragma once
+#include <Swiften/Base/API.h>
+
namespace Swift {
class VCardStorage;
@@ -12,4 +14,5 @@ namespace Swift {
class CapsStorage;
class RosterStorage;
+ class HistoryStorage;
/**
@@ -17,5 +20,5 @@ namespace Swift {
* controllers.
*/
- class Storages {
+ class SWIFTEN_API Storages {
public:
virtual ~Storages();
@@ -25,4 +28,5 @@ namespace Swift {
virtual CapsStorage* getCapsStorage() const = 0;
virtual RosterStorage* getRosterStorage() const = 0;
+ virtual HistoryStorage* getHistoryStorage() const = 0;
};
}
diff --git a/Swiften/Client/UnitTest/ClientBlockListManagerTest.cpp b/Swiften/Client/UnitTest/ClientBlockListManagerTest.cpp
new file mode 100644
index 0000000..dd6c95d
--- /dev/null
+++ b/Swiften/Client/UnitTest/ClientBlockListManagerTest.cpp
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2013 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include <algorithm>
+
+#include <Swiften/Base/foreach.h>
+
+#include <Swiften/Client/StanzaChannel.h>
+#include <Swiften/Client/DummyStanzaChannel.h>
+#include <Swiften/Client/ClientBlockListManager.h>
+#include <Swiften/Queries/IQRouter.h>
+#include <Swiften/Elements/IQ.h>
+
+using namespace Swift;
+
+class ClientBlockListManagerTest : public CppUnit::TestFixture {
+ CPPUNIT_TEST_SUITE(ClientBlockListManagerTest);
+ CPPUNIT_TEST(testFetchBlockList);
+ CPPUNIT_TEST(testBlockCommand);
+ CPPUNIT_TEST(testUnblockCommand);
+ CPPUNIT_TEST(testUnblockAllCommand);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void setUp() {
+ ownJID_ = JID("kev@wonderland.lit");
+ stanzaChannel_ = new DummyStanzaChannel();
+ iqRouter_ = new IQRouter(stanzaChannel_);
+ iqRouter_->setJID(ownJID_);
+ clientBlockListManager_ = new ClientBlockListManager(iqRouter_);
+ }
+
+ void testFetchBlockList() {
+ std::vector<JID> blockJids;
+ blockJids.push_back(JID("romeo@montague.net"));
+ blockJids.push_back(JID("iago@shakespeare.lit"));
+ helperInitialBlockListFetch(blockJids);
+
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), clientBlockListManager_->getBlockList()->getItems().size());
+ }
+
+ void testBlockCommand() {
+ // start with an already fetched block list
+ helperInitialBlockListFetch(std::vector<JID>(1, JID("iago@shakespeare.lit")));
+
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), clientBlockListManager_->getBlockList()->getItems().size());
+ CPPUNIT_ASSERT_EQUAL(BlockList::Available, clientBlockListManager_->getBlockList()->getState());
+
+ GenericRequest<BlockPayload>::ref blockRequest = clientBlockListManager_->createBlockJIDRequest(JID("romeo@montague.net"));
+ blockRequest->send();
+ IQ::ref request = stanzaChannel_->getStanzaAtIndex<IQ>(2);
+ CPPUNIT_ASSERT(request.get() != NULL);
+ boost::shared_ptr<BlockPayload> blockPayload = request->getPayload<BlockPayload>();
+ CPPUNIT_ASSERT(blockPayload.get() != NULL);
+ CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.net"), blockPayload->getItems().at(0));
+
+ IQ::ref blockRequestResponse = IQ::createResult(request->getFrom(), JID(), request->getID());
+ stanzaChannel_->sendIQ(blockRequestResponse);
+ stanzaChannel_->onIQReceived(blockRequestResponse);
+
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), clientBlockListManager_->getBlockList()->getItems().size());
+
+ // send block push
+ boost::shared_ptr<BlockPayload> pushPayload = boost::make_shared<BlockPayload>();
+ pushPayload->addItem(JID("romeo@montague.net"));
+ IQ::ref blockPush = IQ::createRequest(IQ::Set, ownJID_, "push1", pushPayload);
+ stanzaChannel_->sendIQ(blockPush);
+ stanzaChannel_->onIQReceived(blockPush);
+
+ std::vector<JID> blockedJIDs = clientBlockListManager_->getBlockList()->getItems();
+ CPPUNIT_ASSERT(blockedJIDs.end() != std::find(blockedJIDs.begin(), blockedJIDs.end(), JID("romeo@montague.net")));
+ }
+
+ void testUnblockCommand() {
+ // start with an already fetched block list
+ std::vector<JID> initialBlockList = std::vector<JID>(1, JID("iago@shakespeare.lit"));
+ initialBlockList.push_back(JID("romeo@montague.net"));
+ helperInitialBlockListFetch(initialBlockList);
+
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), clientBlockListManager_->getBlockList()->getItems().size());
+ CPPUNIT_ASSERT_EQUAL(BlockList::Available, clientBlockListManager_->getBlockList()->getState());
+
+ GenericRequest<UnblockPayload>::ref unblockRequest = clientBlockListManager_->createUnblockJIDRequest(JID("romeo@montague.net"));
+ unblockRequest->send();
+ IQ::ref request = stanzaChannel_->getStanzaAtIndex<IQ>(2);
+ CPPUNIT_ASSERT(request.get() != NULL);
+ boost::shared_ptr<UnblockPayload> unblockPayload = request->getPayload<UnblockPayload>();
+ CPPUNIT_ASSERT(unblockPayload.get() != NULL);
+ CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.net"), unblockPayload->getItems().at(0));
+
+ IQ::ref unblockRequestResponse = IQ::createResult(request->getFrom(), JID(), request->getID());
+ stanzaChannel_->sendIQ(unblockRequestResponse);
+ stanzaChannel_->onIQReceived(unblockRequestResponse);
+
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), clientBlockListManager_->getBlockList()->getItems().size());
+
+ // send block push
+ boost::shared_ptr<UnblockPayload> pushPayload = boost::make_shared<UnblockPayload>();
+ pushPayload->addItem(JID("romeo@montague.net"));
+ IQ::ref unblockPush = IQ::createRequest(IQ::Set, ownJID_, "push1", pushPayload);
+ stanzaChannel_->sendIQ(unblockPush);
+ stanzaChannel_->onIQReceived(unblockPush);
+
+ std::vector<JID> blockedJIDs = clientBlockListManager_->getBlockList()->getItems();
+ CPPUNIT_ASSERT(blockedJIDs.end() == std::find(blockedJIDs.begin(), blockedJIDs.end(), JID("romeo@montague.net")));
+ }
+
+ void testUnblockAllCommand() {
+ // start with an already fetched block list
+ std::vector<JID> initialBlockList = std::vector<JID>(1, JID("iago@shakespeare.lit"));
+ initialBlockList.push_back(JID("romeo@montague.net"));
+ initialBlockList.push_back(JID("benvolio@montague.net"));
+ helperInitialBlockListFetch(initialBlockList);
+
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), clientBlockListManager_->getBlockList()->getItems().size());
+ CPPUNIT_ASSERT_EQUAL(BlockList::Available, clientBlockListManager_->getBlockList()->getState());
+
+ GenericRequest<UnblockPayload>::ref unblockRequest = clientBlockListManager_->createUnblockAllRequest();
+ unblockRequest->send();
+ IQ::ref request = stanzaChannel_->getStanzaAtIndex<IQ>(2);
+ CPPUNIT_ASSERT(request.get() != NULL);
+ boost::shared_ptr<UnblockPayload> unblockPayload = request->getPayload<UnblockPayload>();
+ CPPUNIT_ASSERT(unblockPayload.get() != NULL);
+ CPPUNIT_ASSERT_EQUAL(true, unblockPayload->getItems().empty());
+
+ IQ::ref unblockRequestResponse = IQ::createResult(request->getFrom(), JID(), request->getID());
+ stanzaChannel_->sendIQ(unblockRequestResponse);
+ stanzaChannel_->onIQReceived(unblockRequestResponse);
+
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), clientBlockListManager_->getBlockList()->getItems().size());
+
+ // send block push
+ boost::shared_ptr<UnblockPayload> pushPayload = boost::make_shared<UnblockPayload>();
+ IQ::ref unblockPush = IQ::createRequest(IQ::Set, ownJID_, "push1", pushPayload);
+ stanzaChannel_->sendIQ(unblockPush);
+ stanzaChannel_->onIQReceived(unblockPush);
+
+ CPPUNIT_ASSERT_EQUAL(true, clientBlockListManager_->getBlockList()->getItems().empty());
+ }
+
+ void tearDown() {
+ delete clientBlockListManager_;
+ delete iqRouter_;
+ delete stanzaChannel_;
+ }
+
+ private:
+ void helperInitialBlockListFetch(const std::vector<JID>& blockedJids) {
+ boost::shared_ptr<BlockList> blockList = clientBlockListManager_->requestBlockList();
+ CPPUNIT_ASSERT(blockList);
+
+ // check for IQ request
+ IQ::ref request = stanzaChannel_->getStanzaAtIndex<IQ>(0);
+ CPPUNIT_ASSERT(request.get() != NULL);
+ boost::shared_ptr<BlockListPayload> requestPayload = request->getPayload<BlockListPayload>();
+ CPPUNIT_ASSERT(requestPayload.get() != NULL);
+
+ CPPUNIT_ASSERT_EQUAL(BlockList::Requesting, blockList->getState());
+ CPPUNIT_ASSERT_EQUAL(BlockList::Requesting, clientBlockListManager_->getBlockList()->getState());
+
+ // build IQ response
+ boost::shared_ptr<BlockListPayload> responsePayload = boost::make_shared<BlockListPayload>();
+ foreach(const JID& jid, blockedJids) {
+ responsePayload->addItem(jid);
+ }
+
+ IQ::ref response = IQ::createResult(ownJID_, JID(), request->getID(), responsePayload);
+ stanzaChannel_->sendIQ(response);
+ stanzaChannel_->onIQReceived(response);
+
+ CPPUNIT_ASSERT_EQUAL(BlockList::Available, clientBlockListManager_->getBlockList()->getState());
+ CPPUNIT_ASSERT(responsePayload->getItems() == clientBlockListManager_->getBlockList()->getItems());
+ }
+
+
+ private:
+ JID ownJID_;
+ IQRouter* iqRouter_;
+ DummyStanzaChannel* stanzaChannel_;
+ ClientBlockListManager* clientBlockListManager_;
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(ClientBlockListManagerTest);
+
diff --git a/Swiften/Client/UnitTest/ClientSessionTest.cpp b/Swiften/Client/UnitTest/ClientSessionTest.cpp
index 6793643..4e1fc31 100644
--- a/Swiften/Client/UnitTest/ClientSessionTest.cpp
+++ b/Swiften/Client/UnitTest/ClientSessionTest.cpp
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2014 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -12,7 +12,10 @@
#include <boost/smart_ptr/make_shared.hpp>
+#include <Swiften/IDN/IDNConverter.h>
+#include <Swiften/IDN/PlatformIDNConverter.h>
#include <Swiften/Session/SessionStream.h>
#include <Swiften/Client/ClientSession.h>
#include <Swiften/Elements/Message.h>
+#include <Swiften/Elements/AuthChallenge.h>
#include <Swiften/Elements/StartTLSRequest.h>
#include <Swiften/Elements/StreamFeatures.h>
@@ -31,4 +34,6 @@
#include <Swiften/TLS/SimpleCertificate.h>
#include <Swiften/TLS/BlindCertificateTrustChecker.h>
+#include <Swiften/Crypto/CryptoProvider.h>
+#include <Swiften/Crypto/PlatformCryptoProvider.h>
using namespace Swift;
@@ -48,6 +53,8 @@ class ClientSessionTest : public CppUnit::TestFixture {
CPPUNIT_TEST(testAuthenticate_PLAINOverNonTLS);
CPPUNIT_TEST(testAuthenticate_RequireTLS);
+ CPPUNIT_TEST(testAuthenticate_EXTERNAL);
CPPUNIT_TEST(testStreamManagement);
CPPUNIT_TEST(testStreamManagement_Failed);
+ CPPUNIT_TEST(testUnexpectedChallenge);
CPPUNIT_TEST(testFinishAcksStanzas);
/*
@@ -67,4 +74,6 @@ class ClientSessionTest : public CppUnit::TestFixture {
public:
void setUp() {
+ crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create());
+ idnConverter = boost::shared_ptr<IDNConverter>(PlatformIDNConverter::create());
server = boost::make_shared<MockSessionStream>();
sessionFinishedReceived = false;
@@ -248,4 +257,32 @@ class ClientSessionTest : public CppUnit::TestFixture {
}
+ void testAuthenticate_EXTERNAL() {
+ boost::shared_ptr<ClientSession> session(createSession());
+ session->start();
+ server->receiveStreamStart();
+ server->sendStreamStart();
+ server->sendStreamFeaturesWithEXTERNALAuthentication();
+ server->receiveAuthRequest("EXTERNAL");
+ server->sendAuthSuccess();
+ server->receiveStreamStart();
+
+ session->finish();
+ }
+
+ void testUnexpectedChallenge() {
+ boost::shared_ptr<ClientSession> session(createSession());
+ session->start();
+ server->receiveStreamStart();
+ server->sendStreamStart();
+ server->sendStreamFeaturesWithEXTERNALAuthentication();
+ server->receiveAuthRequest("EXTERNAL");
+ server->sendChallenge();
+ server->sendChallenge();
+
+ CPPUNIT_ASSERT_EQUAL(ClientSession::Finished, session->getState());
+ CPPUNIT_ASSERT(sessionFinishedReceived);
+ CPPUNIT_ASSERT(sessionFinishedError);
+ }
+
void testStreamManagement() {
boost::shared_ptr<ClientSession> session(createSession());
@@ -309,5 +346,5 @@ class ClientSessionTest : public CppUnit::TestFixture {
private:
boost::shared_ptr<ClientSession> createSession() {
- boost::shared_ptr<ClientSession> session = ClientSession::create(JID("me@foo.com"), server);
+ boost::shared_ptr<ClientSession> session = ClientSession::create(JID("me@foo.com"), server, idnConverter.get(), crypto.get());
session->onFinished.connect(boost::bind(&ClientSessionTest::handleSessionFinished, this, _1));
session->onNeedCredentials.connect(boost::bind(&ClientSessionTest::handleSessionNeedCredentials, this));
@@ -345,9 +382,9 @@ class ClientSessionTest : public CppUnit::TestFixture {
public:
struct Event {
- Event(boost::shared_ptr<Element> element) : element(element), footer(false) {}
+ Event(boost::shared_ptr<ToplevelElement> element) : element(element), footer(false) {}
Event(const ProtocolHeader& header) : header(header), footer(false) {}
Event() : footer(true) {}
- boost::shared_ptr<Element> element;
+ boost::shared_ptr<ToplevelElement> element;
boost::optional<ProtocolHeader> header;
bool footer;
@@ -373,5 +410,5 @@ class ClientSessionTest : public CppUnit::TestFixture {
}
- virtual void writeElement(boost::shared_ptr<Element> element) {
+ virtual void writeElement(boost::shared_ptr<ToplevelElement> element) {
receivedEvents.push_back(Event(element));
}
@@ -400,4 +437,8 @@ class ClientSessionTest : public CppUnit::TestFixture {
}
+ virtual std::vector<Certificate::ref> getPeerCertificateChain() const {
+ return std::vector<Certificate::ref>();
+ }
+
virtual boost::shared_ptr<CertificateVerificationError> getPeerCertificateVerificationError() const {
return boost::shared_ptr<CertificateVerificationError>();
@@ -441,4 +482,8 @@ class ClientSessionTest : public CppUnit::TestFixture {
}
+ void sendChallenge() {
+ onElementReceived(boost::make_shared<AuthChallenge>());
+ }
+
void sendStreamError() {
onElementReceived(boost::make_shared<StreamError>());
@@ -467,4 +512,10 @@ class ClientSessionTest : public CppUnit::TestFixture {
}
+ void sendStreamFeaturesWithEXTERNALAuthentication() {
+ boost::shared_ptr<StreamFeatures> streamFeatures(new StreamFeatures());
+ streamFeatures->addAuthenticationMechanism("EXTERNAL");
+ onElementReceived(streamFeatures);
+ }
+
void sendStreamFeaturesWithUnknownAuthentication() {
boost::shared_ptr<StreamFeatures> streamFeatures(new StreamFeatures());
@@ -572,4 +623,5 @@ class ClientSessionTest : public CppUnit::TestFixture {
};
+ boost::shared_ptr<IDNConverter> idnConverter;
boost::shared_ptr<MockSessionStream> server;
bool sessionFinishedReceived;
@@ -577,4 +629,5 @@ class ClientSessionTest : public CppUnit::TestFixture {
boost::shared_ptr<Error> sessionFinishedError;
BlindCertificateTrustChecker* blindCertificateTrustChecker;
+ boost::shared_ptr<CryptoProvider> crypto;
};
diff --git a/Swiften/Client/UnitTest/NickResolverTest.cpp b/Swiften/Client/UnitTest/NickResolverTest.cpp
index dfc90fe..a8b011c 100644
--- a/Swiften/Client/UnitTest/NickResolverTest.cpp
+++ b/Swiften/Client/UnitTest/NickResolverTest.cpp
@@ -5,4 +5,10 @@
*/
+/*
+ * Copyright (c) 2013 Remko Tronçon
+ * Licensed under the GNU General Public License.
+ * See the COPYING file for more information.
+ */
+
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
@@ -15,4 +21,6 @@
#include <Swiften/Queries/IQRouter.h>
#include <Swiften/Client/DummyStanzaChannel.h>
+#include <Swiften/Crypto/CryptoProvider.h>
+#include <Swiften/Crypto/PlatformCryptoProvider.h>
using namespace Swift;
@@ -35,9 +43,10 @@ class NickResolverTest : public CppUnit::TestFixture {
public:
void setUp() {
+ crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create());
ownJID_ = JID("kev@wonderland.lit");
xmppRoster_ = new XMPPRosterImpl();
stanzaChannel_ = new DummyStanzaChannel();
iqRouter_ = new IQRouter(stanzaChannel_);
- vCardStorage_ = new VCardMemoryStorage();
+ vCardStorage_ = new VCardMemoryStorage(crypto.get());
vCardManager_ = new VCardManager(ownJID_, iqRouter_, vCardStorage_);
registry_ = new MUCRegistry();
@@ -145,5 +154,5 @@ class NickResolverTest : public CppUnit::TestFixture {
NickResolver* resolver_;
JID ownJID_;
-
+ boost::shared_ptr<CryptoProvider> crypto;
};
diff --git a/Swiften/Client/XMLBeautifier.cpp b/Swiften/Client/XMLBeautifier.cpp
index b70fc48..5d083ff 100644
--- a/Swiften/Client/XMLBeautifier.cpp
+++ b/Swiften/Client/XMLBeautifier.cpp
@@ -5,4 +5,10 @@
*/
+/*
+ * Copyright (c) 2014 Remko Tronçon
+ * Licensed under the GNU General Public License.
+ * See the COPYING file for more information.
+ */
+
#include <sstream>
#include <stack>
@@ -39,11 +45,11 @@ void XMLBeautifier::indent() {
// all bold but reset
-const char colorBlue[] = "\x1b[01;34m";
-const char colorCyan[] = "\x1b[01;36m";
-const char colorGreen[] = "\x1b[01;32m";
-const char colorMagenta[] = "\x1b[01;35m";
-const char colorRed[] = "\x1b[01;31m";
-const char colorReset[] = "\x1b[0m";
-const char colorYellow[] = "\x1b[01;33m";
+// static const char colorBlue[] = "\x1b[01;34m";
+static const char colorCyan[] = "\x1b[01;36m";
+static const char colorGreen[] = "\x1b[01;32m";
+// static const char colorMagenta[] = "\x1b[01;35m";
+static const char colorRed[] = "\x1b[01;31m";
+static const char colorReset[] = "\x1b[0m";
+static const char colorYellow[] = "\x1b[01;33m";
diff --git a/Swiften/Client/XMLBeautifier.h b/Swiften/Client/XMLBeautifier.h
index 44dfd20..25ecd18 100644
--- a/Swiften/Client/XMLBeautifier.h
+++ b/Swiften/Client/XMLBeautifier.h
@@ -5,6 +5,13 @@
*/
+/*
+* Copyright (c) 2014 Remko Tronçon and Kevin Smith
+* Licensed under the GNU General Public License v3.
+* See Documentation/Licenses/GPLv3.txt for more information.
+*/
+
#pragma once
+#include <sstream>
#include <string>
#include <stack>