diff options
Diffstat (limited to 'Swiften/Client')
23 files changed, 450 insertions, 331 deletions
| diff --git a/Swiften/Client/Client.cpp b/Swiften/Client/Client.cpp index 7918c46..c53bcaf 100644 --- a/Swiften/Client/Client.cpp +++ b/Swiften/Client/Client.cpp @@ -4,38 +4,39 @@   * See Documentation/Licenses/GPLv3.txt for more information.   */ -#include "Swiften/Client/Client.h" - -#include "Swiften/Queries/Responders/SoftwareVersionResponder.h" -#include "Swiften/Roster/XMPPRosterImpl.h" -#include "Swiften/Roster/XMPPRosterController.h" -#include "Swiften/Presence/PresenceOracle.h" -#include "Swiften/Presence/StanzaChannelPresenceSender.h" -#include "Swiften/Presence/DirectedPresenceSender.h" -#include "Swiften/MUC/MUCRegistry.h" -#include "Swiften/MUC/MUCManager.h" -#include "Swiften/Client/MemoryStorages.h" -#include "Swiften/VCards/VCardManager.h" -#include "Swiften/VCards/VCardManager.h" -#include "Swiften/Avatars/AvatarManagerImpl.h" -#include "Swiften/Disco/CapsManager.h" -#include "Swiften/Disco/EntityCapsManager.h" -#include "Swiften/Disco/ClientDiscoManager.h" -#include "Swiften/Client/NickResolver.h" -#include "Swiften/Presence/SubscriptionManager.h" -#include "Swiften/TLS/BlindCertificateTrustChecker.h" +#include <Swiften/Client/Client.h> + +#include <Swiften/Queries/Responders/SoftwareVersionResponder.h> +#include <Swiften/Roster/XMPPRosterImpl.h> +#include <Swiften/Roster/XMPPRosterController.h> +#include <Swiften/Presence/PresenceOracle.h> +#include <Swiften/Presence/StanzaChannelPresenceSender.h> +#include <Swiften/Presence/DirectedPresenceSender.h> +#include <Swiften/MUC/MUCRegistry.h> +#include <Swiften/MUC/MUCManager.h> +#include <Swiften/Client/MemoryStorages.h> +#include <Swiften/VCards/VCardManager.h> +#include <Swiften/VCards/VCardManager.h> +#include <Swiften/Avatars/AvatarManagerImpl.h> +#include <Swiften/Disco/CapsManager.h> +#include <Swiften/Disco/EntityCapsManager.h> +#include <Swiften/Disco/ClientDiscoManager.h> +#include <Swiften/Client/NickResolver.h> +#include <Swiften/Presence/SubscriptionManager.h> +#include <Swiften/TLS/BlindCertificateTrustChecker.h>  #include <Swiften/Client/NickManagerImpl.h> +#include <Swiften/Client/ClientSession.h>  namespace Swift { -Client::Client(const JID& jid, const std::string& password, NetworkFactories* networkFactories, Storages* storages) : CoreClient(jid, password, networkFactories), storages(storages) { +Client::Client(const JID& jid, const SafeString& password, NetworkFactories* networkFactories, Storages* storages) : CoreClient(jid, password, networkFactories), storages(storages) {  	memoryStorages = new MemoryStorages();  	softwareVersionResponder = new SoftwareVersionResponder(getIQRouter());  	softwareVersionResponder->start();  	roster = new XMPPRosterImpl(); -	rosterController = new XMPPRosterController(getIQRouter(), roster); +	rosterController = new XMPPRosterController(getIQRouter(), roster, getStorages()->getRosterStorage());  	subscriptionManager = new SubscriptionManager(getStanzaChannel()); @@ -98,6 +99,11 @@ void Client::setSoftwareVersion(const std::string& name, const std::string& vers  }  void Client::requestRoster() { +	// FIXME: We should set this once when the session is finished, but there +	// is currently no callback for this +	if (getSession()) { +		rosterController->setUseVersioning(getSession()->getRosterVersioningSupported()); +	}  	rosterController->requestRoster();  } diff --git a/Swiften/Client/Client.h b/Swiften/Client/Client.h index 083b8a0..08289a5 100644 --- a/Swiften/Client/Client.h +++ b/Swiften/Client/Client.h @@ -6,7 +6,9 @@  #pragma once -#include "Swiften/Client/CoreClient.h" +#include <Swiften/Client/CoreClient.h> + +#include <Swiften/Base/SafeString.h>  namespace Swift {  	class SoftwareVersionResponder; @@ -47,7 +49,7 @@ namespace Swift {  			 *	this is NULL,  			 *	all data will be stored in memory (and be lost on shutdown)  			 */ -			Client(const JID& jid, const std::string& password, NetworkFactories* networkFactories, Storages* storages = NULL); +			Client(const JID& jid, const SafeString& password, NetworkFactories* networkFactories, Storages* storages = NULL);  			~Client(); @@ -85,12 +87,12 @@ namespace Swift {  			/**  			 * Returns the last received presence for the given (full) JID.  			 */ -			Presence::ref getLastPresence(const JID& jid) const; +			boost::shared_ptr<Presence> getLastPresence(const JID& jid) const;  			/**  			 * Returns the presence with the highest priority received for the given JID.  			 */ -			Presence::ref getHighestPriorityPresence(const JID& bareJID) const; +			boost::shared_ptr<Presence> getHighestPriorityPresence(const JID& bareJID) const;  			PresenceOracle* getPresenceOracle() const {  				return presenceOracle; @@ -142,7 +144,7 @@ namespace Swift {  			/**  			 * This signal is emitted when a JID changes presence.  			 */ -			boost::signal<void (Presence::ref)> onPresenceChange; +			boost::signal<void (boost::shared_ptr<Presence>)> onPresenceChange;  		private:  			Storages* getStorages() const; diff --git a/Swiften/Client/ClientOptions.h b/Swiften/Client/ClientOptions.h new file mode 100644 index 0000000..0766402 --- /dev/null +++ b/Swiften/Client/ClientOptions.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +namespace Swift { +	struct ClientOptions { +		enum UseTLS { +			NeverUseTLS, +			UseTLSWhenAvailable +		}; + +		ClientOptions() : useStreamCompression(true), useTLS(UseTLSWhenAvailable), allowPLAINWithoutTLS(false), useStreamResumption(false), forgetPassword(false) { +		} + +		/** +		 * Whether ZLib stream compression should be used when available. +		 * +		 * Default: true +		 */ +		bool useStreamCompression; + +		/** +		 * Sets whether TLS encryption should be used. +		 * +		 * Default: UseTLSWhenAvailable +		 */ +		UseTLS useTLS; + +		/** +		 * Sets whether plaintext authentication is  +		 * allowed over non-TLS-encrypted connections. +		 * +		 * Default: false +		 */ +		bool allowPLAINWithoutTLS; + +		/** +		 * Use XEP-196 stream resumption when available. +		 * +		 * Default: false +		 */ +		bool useStreamResumption; + +		/** +		 * Forget the password once it's used. +		 * This makes the Client useless after the first login attempt. +		 * +		 * FIXME: This is a temporary workaround. +		 * +		 * Default: false +		 */ +		bool forgetPassword; +	}; +} diff --git a/Swiften/Client/ClientSession.cpp b/Swiften/Client/ClientSession.cpp index e1c1d8e..8945e9a 100644 --- a/Swiften/Client/ClientSession.cpp +++ b/Swiften/Client/ClientSession.cpp @@ -4,41 +4,42 @@   * See Documentation/Licenses/GPLv3.txt for more information.   */ -#include "Swiften/Client/ClientSession.h" +#include <Swiften/Client/ClientSession.h>  #include <boost/bind.hpp>  #include <boost/uuid/uuid.hpp>  #include <boost/uuid/uuid_io.hpp>  #include <boost/uuid/uuid_generators.hpp> +#include <boost/smart_ptr/make_shared.hpp> -#include "Swiften/Elements/ProtocolHeader.h" -#include "Swiften/Elements/StreamFeatures.h" -#include "Swiften/Elements/StreamError.h" -#include "Swiften/Elements/StartTLSRequest.h" -#include "Swiften/Elements/StartTLSFailure.h" -#include "Swiften/Elements/TLSProceed.h" -#include "Swiften/Elements/AuthRequest.h" -#include "Swiften/Elements/AuthSuccess.h" -#include "Swiften/Elements/AuthFailure.h" -#include "Swiften/Elements/AuthChallenge.h" -#include "Swiften/Elements/AuthResponse.h" -#include "Swiften/Elements/Compressed.h" -#include "Swiften/Elements/CompressFailure.h" -#include "Swiften/Elements/CompressRequest.h" -#include "Swiften/Elements/EnableStreamManagement.h" -#include "Swiften/Elements/StreamManagementEnabled.h" -#include "Swiften/Elements/StreamManagementFailed.h" -#include "Swiften/Elements/StartSession.h" -#include "Swiften/Elements/StanzaAck.h" -#include "Swiften/Elements/StanzaAckRequest.h" -#include "Swiften/Elements/IQ.h" -#include "Swiften/Elements/ResourceBind.h" -#include "Swiften/SASL/PLAINClientAuthenticator.h" -#include "Swiften/SASL/SCRAMSHA1ClientAuthenticator.h" -#include "Swiften/SASL/DIGESTMD5ClientAuthenticator.h" -#include "Swiften/Session/SessionStream.h" -#include "Swiften/TLS/CertificateTrustChecker.h" -#include "Swiften/TLS/ServerIdentityVerifier.h" +#include <Swiften/Elements/ProtocolHeader.h> +#include <Swiften/Elements/StreamFeatures.h> +#include <Swiften/Elements/StreamError.h> +#include <Swiften/Elements/StartTLSRequest.h> +#include <Swiften/Elements/StartTLSFailure.h> +#include <Swiften/Elements/TLSProceed.h> +#include <Swiften/Elements/AuthRequest.h> +#include <Swiften/Elements/AuthSuccess.h> +#include <Swiften/Elements/AuthFailure.h> +#include <Swiften/Elements/AuthChallenge.h> +#include <Swiften/Elements/AuthResponse.h> +#include <Swiften/Elements/Compressed.h> +#include <Swiften/Elements/CompressFailure.h> +#include <Swiften/Elements/CompressRequest.h> +#include <Swiften/Elements/EnableStreamManagement.h> +#include <Swiften/Elements/StreamManagementEnabled.h> +#include <Swiften/Elements/StreamManagementFailed.h> +#include <Swiften/Elements/StartSession.h> +#include <Swiften/Elements/StanzaAck.h> +#include <Swiften/Elements/StanzaAckRequest.h> +#include <Swiften/Elements/IQ.h> +#include <Swiften/Elements/ResourceBind.h> +#include <Swiften/SASL/PLAINClientAuthenticator.h> +#include <Swiften/SASL/SCRAMSHA1ClientAuthenticator.h> +#include <Swiften/SASL/DIGESTMD5ClientAuthenticator.h> +#include <Swiften/Session/SessionStream.h> +#include <Swiften/TLS/CertificateTrustChecker.h> +#include <Swiften/TLS/ServerIdentityVerifier.h>  namespace Swift { @@ -54,6 +55,7 @@ ClientSession::ClientSession(  			needSessionStart(false),  			needResourceBind(false),  			needAcking(false), +			rosterVersioningSupported(false),  			authenticator(NULL),  			certificateTrustChecker(NULL) {  } @@ -173,17 +175,17 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) {  		if (streamFeatures->hasStartTLS() && stream->supportsTLSEncryption() && useTLS != NeverUseTLS) {  			state = WaitingForEncrypt; -			stream->writeElement(boost::shared_ptr<StartTLSRequest>(new StartTLSRequest())); +			stream->writeElement(boost::make_shared<StartTLSRequest>());  		}  		else if (useStreamCompression && streamFeatures->hasCompressionMethod("zlib")) {  			state = Compressing; -			stream->writeElement(boost::shared_ptr<CompressRequest>(new CompressRequest("zlib"))); +			stream->writeElement(boost::make_shared<CompressRequest>("zlib"));  		}  		else if (streamFeatures->hasAuthenticationMechanisms()) {  			if (stream->hasTLSCertificate()) {  				if (streamFeatures->hasAuthenticationMechanism("EXTERNAL")) {  					state = Authenticating; -					stream->writeElement(boost::shared_ptr<Element>(new AuthRequest("EXTERNAL", ""))); +					stream->writeElement(boost::make_shared<AuthRequest>("EXTERNAL", createSafeByteArray("")));  				}  				else {  					finishSession(Error::TLSClientCertificateError); @@ -191,7 +193,7 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) {  			}  			else if (streamFeatures->hasAuthenticationMechanism("EXTERNAL")) {  				state = Authenticating; -				stream->writeElement(boost::shared_ptr<Element>(new AuthRequest("EXTERNAL", ""))); +				stream->writeElement(boost::make_shared<AuthRequest>("EXTERNAL", createSafeByteArray("")));  			}  			else if (streamFeatures->hasAuthenticationMechanism("SCRAM-SHA-1") || streamFeatures->hasAuthenticationMechanism("SCRAM-SHA-1-PLUS")) {  				std::ostringstream s; @@ -223,6 +225,7 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) {  		}  		else {  			// Start the session +			rosterVersioningSupported = streamFeatures->hasRosterVersioning();  			stream->setWhitespacePingEnabled(true);  			needSessionStart = streamFeatures->hasSession();  			needResourceBind = streamFeatures->hasResourceBind(); @@ -247,10 +250,10 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) {  		finishSession(Error::CompressionFailedError);  	}  	else if (boost::dynamic_pointer_cast<StreamManagementEnabled>(element)) { -		stanzaAckRequester_ = boost::shared_ptr<StanzaAckRequester>(new StanzaAckRequester()); +		stanzaAckRequester_ = boost::make_shared<StanzaAckRequester>();  		stanzaAckRequester_->onRequestAck.connect(boost::bind(&ClientSession::requestAck, shared_from_this()));  		stanzaAckRequester_->onStanzaAcked.connect(boost::bind(&ClientSession::handleStanzaAcked, shared_from_this(), _1)); -		stanzaAckResponder_ = boost::shared_ptr<StanzaAckResponder>(new StanzaAckResponder()); +		stanzaAckResponder_ = boost::make_shared<StanzaAckResponder>();  		stanzaAckResponder_->onAck.connect(boost::bind(&ClientSession::ack, shared_from_this(), _1));  		needAcking = false;  		continueSessionInitialization(); @@ -263,7 +266,7 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) {  		checkState(Authenticating);  		assert(authenticator);  		if (authenticator->setChallenge(challenge->getValue())) { -			stream->writeElement(boost::shared_ptr<AuthResponse>(new AuthResponse(authenticator->getResponse()))); +			stream->writeElement(boost::make_shared<AuthResponse>(authenticator->getResponse()));  		}  		else {  			finishSession(Error::AuthenticationFailedError); @@ -272,6 +275,8 @@ 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;  			finishSession(Error::ServerVerificationFailedError);  		}  		else { @@ -305,7 +310,7 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) {  void ClientSession::continueSessionInitialization() {  	if (needResourceBind) {  		state = BindingResource; -		boost::shared_ptr<ResourceBind> resourceBind(new ResourceBind()); +		boost::shared_ptr<ResourceBind> resourceBind(boost::make_shared<ResourceBind>());  		if (!localJID.getResource().empty()) {  			resourceBind->setResource(localJID.getResource());  		} @@ -313,11 +318,11 @@ void ClientSession::continueSessionInitialization() {  	}  	else if (needAcking) {  		state = EnablingSessionManagement; -		stream->writeElement(boost::shared_ptr<EnableStreamManagement>(new EnableStreamManagement())); +		stream->writeElement(boost::make_shared<EnableStreamManagement>());  	}  	else if (needSessionStart) {  		state = StartingSession; -		sendStanza(IQ::createRequest(IQ::Set, JID(), "session-start", boost::shared_ptr<StartSession>(new StartSession()))); +		sendStanza(IQ::createRequest(IQ::Set, JID(), "session-start", boost::make_shared<StartSession>()));  	}  	else {  		state = Initialized; @@ -333,11 +338,11 @@ bool ClientSession::checkState(State state) {  	return true;  } -void ClientSession::sendCredentials(const std::string& password) { +void ClientSession::sendCredentials(const SafeByteArray& password) {  	assert(WaitingForCredentials);  	state = Authenticating;  	authenticator->setCredentials(localJID.getNode(), password); -	stream->writeElement(boost::shared_ptr<AuthRequest>(new AuthRequest(authenticator->getName(), authenticator->getResponse()))); +	stream->writeElement(boost::make_shared<AuthRequest>(authenticator->getName(), authenticator->getResponse()));  }  void ClientSession::handleTLSEncrypted() { @@ -354,8 +359,7 @@ void ClientSession::handleTLSEncrypted() {  			continueAfterTLSEncrypted();  		}  		else { -			boost::shared_ptr<CertificateVerificationError> identityError(new CertificateVerificationError(CertificateVerificationError::InvalidServerIdentity)); -			checkTrustOrFinish(certificate, identityError); +			checkTrustOrFinish(certificate, boost::make_shared<CertificateVerificationError>(CertificateVerificationError::InvalidServerIdentity));  		}  	}  } @@ -407,19 +411,22 @@ void ClientSession::finish() {  }  void ClientSession::finishSession(Error::Type error) { -	finishSession(boost::shared_ptr<Swift::ClientSession::Error>(new Swift::ClientSession::Error(error))); +	finishSession(boost::make_shared<Swift::ClientSession::Error>(error));  }  void ClientSession::finishSession(boost::shared_ptr<Swift::Error> error) {  	state = Finishing;  	error_ = error;  	assert(stream->isOpen()); +	if (stanzaAckResponder_) { +		stanzaAckResponder_->handleAckRequestReceived(); +	}  	stream->writeFooter();  	stream->close();  }  void ClientSession::requestAck() { -	stream->writeElement(boost::shared_ptr<StanzaAckRequest>(new StanzaAckRequest())); +	stream->writeElement(boost::make_shared<StanzaAckRequest>());  }  void ClientSession::handleStanzaAcked(boost::shared_ptr<Stanza> stanza) { @@ -427,7 +434,7 @@ void ClientSession::handleStanzaAcked(boost::shared_ptr<Stanza> stanza) {  }  void ClientSession::ack(unsigned int handledStanzasCount) { -	stream->writeElement(boost::shared_ptr<StanzaAck>(new StanzaAck(handledStanzasCount))); +	stream->writeElement(boost::make_shared<StanzaAck>(handledStanzasCount));  }  } diff --git a/Swiften/Client/ClientSession.h b/Swiften/Client/ClientSession.h index 25ee694..ace9868 100644 --- a/Swiften/Client/ClientSession.h +++ b/Swiften/Client/ClientSession.h @@ -6,17 +6,17 @@  #pragma once -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h>  #include <boost/shared_ptr.hpp>  #include <boost/enable_shared_from_this.hpp> -#include "Swiften/Base/Error.h" -#include "Swiften/Session/SessionStream.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/StreamManagement/StanzaAckRequester.h" -#include "Swiften/StreamManagement/StanzaAckResponder.h" +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/Element.h> +#include <Swiften/StreamManagement/StanzaAckRequester.h> +#include <Swiften/StreamManagement/StanzaAckResponder.h>  namespace Swift {  	class ClientAuthenticator; @@ -89,6 +89,10 @@ namespace Swift {  				return stanzaAckRequester_;  			} +			bool getRosterVersioningSupported() const { +				return rosterVersioningSupported; +			} +  			const JID& getLocalJID() const {  				return localJID;  			} @@ -100,7 +104,7 @@ namespace Swift {  				return getState() == Finished;  			} -			void sendCredentials(const std::string& password); +			void sendCredentials(const SafeByteArray& password);  			void sendStanza(boost::shared_ptr<Stanza>);  			void setCertificateTrustChecker(CertificateTrustChecker* checker) { @@ -153,6 +157,7 @@ namespace Swift {  			bool needSessionStart;  			bool needResourceBind;  			bool needAcking; +			bool rosterVersioningSupported;  			ClientAuthenticator* authenticator;  			boost::shared_ptr<StanzaAckRequester> stanzaAckRequester_;  			boost::shared_ptr<StanzaAckResponder> stanzaAckResponder_; diff --git a/Swiften/Client/ClientSessionStanzaChannel.cpp b/Swiften/Client/ClientSessionStanzaChannel.cpp index 6b32b3d..5dc0a42 100644 --- a/Swiften/Client/ClientSessionStanzaChannel.cpp +++ b/Swiften/Client/ClientSessionStanzaChannel.cpp @@ -4,9 +4,10 @@   * See Documentation/Licenses/GPLv3.txt for more information.   */ -#include "Swiften/Client/ClientSessionStanzaChannel.h" +#include <Swiften/Client/ClientSessionStanzaChannel.h>  #include <boost/bind.hpp> +#include <iostream>  namespace Swift { diff --git a/Swiften/Client/ClientSessionStanzaChannel.h b/Swiften/Client/ClientSessionStanzaChannel.h index 8a56301..47fb50e 100644 --- a/Swiften/Client/ClientSessionStanzaChannel.h +++ b/Swiften/Client/ClientSessionStanzaChannel.h @@ -8,12 +8,12 @@  #include <boost/shared_ptr.hpp> -#include "Swiften/Base/IDGenerator.h" -#include "Swiften/Client/ClientSession.h" -#include "Swiften/Client/StanzaChannel.h" -#include "Swiften/Elements/Message.h" -#include "Swiften/Elements/IQ.h" -#include "Swiften/Elements/Presence.h" +#include <Swiften/Base/IDGenerator.h> +#include <Swiften/Client/ClientSession.h> +#include <Swiften/Client/StanzaChannel.h> +#include <Swiften/Elements/Message.h> +#include <Swiften/Elements/IQ.h> +#include <Swiften/Elements/Presence.h>  namespace Swift {  	/** diff --git a/Swiften/Client/ClientXMLTracer.cpp b/Swiften/Client/ClientXMLTracer.cpp new file mode 100644 index 0000000..c1e398d --- /dev/null +++ b/Swiften/Client/ClientXMLTracer.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Client/ClientXMLTracer.h> + +#include <iostream> +#include <boost/bind.hpp> + +namespace Swift { + +ClientXMLTracer::ClientXMLTracer(CoreClient* client) { +	client->onDataRead.connect(boost::bind(&ClientXMLTracer::printData, '<', _1)); +	client->onDataWritten.connect(boost::bind(&ClientXMLTracer::printData, '>', _1)); +} + +void ClientXMLTracer::printData(char direction, const SafeByteArray& data) { +	printLine(direction); +	std::cerr << byteArrayToString(ByteArray(data.begin(), data.end())) << std::endl; +} + +void ClientXMLTracer::printLine(char c) { +	for (unsigned int i = 0; i < 80; ++i) { +		std::cerr << c; +	} +	std::cerr << std::endl; +} + +} diff --git a/Swiften/Client/ClientXMLTracer.h b/Swiften/Client/ClientXMLTracer.h index bca2a54..dd94e0e 100644 --- a/Swiften/Client/ClientXMLTracer.h +++ b/Swiften/Client/ClientXMLTracer.h @@ -6,29 +6,16 @@  #pragma once -#include <boost/bind.hpp> -  #include <Swiften/Client/CoreClient.h> +#include <Swiften/Base/SafeByteArray.h>  namespace Swift {  	class ClientXMLTracer {  		public: -			ClientXMLTracer(CoreClient* client) { -				client->onDataRead.connect(boost::bind(&ClientXMLTracer::printData, '<', _1)); -				client->onDataWritten.connect(boost::bind(&ClientXMLTracer::printData, '>', _1)); -			} +			ClientXMLTracer(CoreClient* client);  		private: -			static void printData(char direction, const std::string& data) { -				printLine(direction); -				std::cerr << data << std::endl; -			} - -			static void printLine(char c) { -				for (unsigned int i = 0; i < 80; ++i) { -					std::cerr << c; -				} -				std::cerr << std::endl; -			} +			static void printData(char direction, const SafeByteArray& data); +			static void printLine(char c);  	};  } diff --git a/Swiften/Client/CoreClient.cpp b/Swiften/Client/CoreClient.cpp index f0c5333..ab9e947 100644 --- a/Swiften/Client/CoreClient.cpp +++ b/Swiften/Client/CoreClient.cpp @@ -4,25 +4,31 @@   * See Documentation/Licenses/GPLv3.txt for more information.   */ -#include "Swiften/Client/CoreClient.h" +#include <Swiften/Client/CoreClient.h>  #include <boost/bind.hpp> +#include <boost/smart_ptr/make_shared.hpp> -#include "Swiften/Client/ClientSession.h" -#include "Swiften/TLS/PlatformTLSFactories.h" -#include "Swiften/TLS/CertificateVerificationError.h" -#include "Swiften/Network/Connector.h" -#include "Swiften/Network/NetworkFactories.h" -#include "Swiften/TLS/PKCS12Certificate.h" -#include "Swiften/Session/BasicSessionStream.h" -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/Base/IDGenerator.h" -#include "Swiften/Client/ClientSessionStanzaChannel.h" +#include <Swiften/Base/IDGenerator.h>  #include <Swiften/Base/Log.h> +#include <Swiften/Base/foreach.h> +#include <Swiften/Base/Algorithm.h> +#include <Swiften/Client/ClientSession.h> +#include <Swiften/TLS/PlatformTLSFactories.h> +#include <Swiften/TLS/CertificateVerificationError.h> +#include <Swiften/Network/ChainedConnector.h> +#include <Swiften/Network/NetworkFactories.h> +#include <Swiften/TLS/PKCS12Certificate.h> +#include <Swiften/Session/BasicSessionStream.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Client/ClientSessionStanzaChannel.h> +#include <Swiften/Network/PlatformProxyProvider.h> +#include <Swiften/Network/SOCKS5ProxiedConnectionFactory.h> +#include <Swiften/Network/HTTPConnectProxiedConnectionFactory.h>  namespace Swift { -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) { +CoreClient::CoreClient(const JID& jid, const SafeByteArray& password, NetworkFactories* networkFactories) : jid_(jid), password_(password), networkFactories(networkFactories), 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)); @@ -47,8 +53,9 @@ CoreClient::~CoreClient() {  	delete stanzaChannel_;  } -void CoreClient::connect() { +void CoreClient::connect(const ClientOptions& o) {  	SWIFT_LOG(debug) << "Connecting" << std::endl; +	options = o;  	connect(jid_.getDomain());  } @@ -56,7 +63,19 @@ void CoreClient::connect(const std::string& host) {  	SWIFT_LOG(debug) << "Connecting to host " << host << std::endl;  	disconnectRequested_ = false;  	assert(!connector_); -	connector_ = Connector::create(host, networkFactories->getDomainNameResolver(), networkFactories->getConnectionFactory(), networkFactories->getTimerFactory()); + +	assert(proxyConnectionFactories.empty()); +	PlatformProxyProvider proxyProvider; +	if(proxyProvider.getSOCKS5Proxy().isValid()) { +		proxyConnectionFactories.push_back(new SOCKS5ProxiedConnectionFactory(networkFactories->getConnectionFactory(), proxyProvider.getSOCKS5Proxy())); +	} +	if(proxyProvider.getHTTPConnectProxy().isValid()) { +		proxyConnectionFactories.push_back(new HTTPConnectProxiedConnectionFactory(networkFactories->getConnectionFactory(), proxyProvider.getHTTPConnectProxy())); +	} +	std::vector<ConnectionFactory*> connectionFactories(proxyConnectionFactories); +	connectionFactories.push_back(networkFactories->getConnectionFactory()); + +	connector_ = boost::make_shared<ChainedConnector>(host, networkFactories->getDomainNameResolver(), connectionFactories, networkFactories->getTimerFactory());  	connector_->onConnectFinished.connect(boost::bind(&CoreClient::handleConnectorFinished, this, _1));  	connector_->setTimeoutMilliseconds(60*1000);  	connector_->start(); @@ -65,7 +84,14 @@ void CoreClient::connect(const std::string& host) {  void CoreClient::handleConnectorFinished(boost::shared_ptr<Connection> connection) {  	connector_->onConnectFinished.disconnect(boost::bind(&CoreClient::handleConnectorFinished, this, _1));  	connector_.reset(); +	foreach(ConnectionFactory* f, proxyConnectionFactories) { +		delete f; +	} +  	if (!connection) { +		if (options.forgetPassword) { +			purgePassword(); +		}  		onDisconnected(disconnectRequested_ ? boost::optional<ClientError>() : boost::optional<ClientError>(ClientError::ConnectionError));  	}  	else { @@ -73,7 +99,7 @@ void CoreClient::handleConnectorFinished(boost::shared_ptr<Connection> connectio  		connection_ = connection;  		assert(!sessionStream_); -		sessionStream_ = boost::shared_ptr<BasicSessionStream>(new BasicSessionStream(ClientStreamType, connection_, getPayloadParserFactories(), getPayloadSerializers(), tlsFactories->getTLSContextFactory(), networkFactories->getTimerFactory())); +		sessionStream_ = boost::make_shared<BasicSessionStream>(ClientStreamType, connection_, getPayloadParserFactories(), getPayloadSerializers(), tlsFactories->getTLSContextFactory(), networkFactories->getTimerFactory());  		if (!certificate_.empty()) {  			sessionStream_->setTLSCertificate(PKCS12Certificate(certificate_, password_));  		} @@ -82,12 +108,13 @@ void CoreClient::handleConnectorFinished(boost::shared_ptr<Connection> connectio  		session_ = ClientSession::create(jid_, sessionStream_);  		session_->setCertificateTrustChecker(certificateTrustChecker); -		session_->setUseStreamCompression(useStreamCompression); -		switch(useTLS) { -			case UseTLSWhenAvailable: +		session_->setUseStreamCompression(options.useStreamCompression); +		session_->setAllowPLAINOverNonTLS(options.allowPLAINWithoutTLS); +		switch(options.useTLS) { +			case ClientOptions::UseTLSWhenAvailable:  				session_->setUseTLS(ClientSession::UseTLSWhenAvailable);  				break; -			case NeverUseTLS: +			case ClientOptions::NeverUseTLS:  				session_->setUseTLS(ClientSession::NeverUseTLS);  				break;  		} @@ -115,6 +142,9 @@ void CoreClient::setCertificate(const std::string& certificate) {  }  void CoreClient::handleSessionFinished(boost::shared_ptr<Error> error) { +	if (options.forgetPassword) { +		purgePassword(); +	}  	session_->onFinished.disconnect(boost::bind(&CoreClient::handleSessionFinished, this, _1));  	session_->onNeedCredentials.disconnect(boost::bind(&CoreClient::handleNeedCredentials, this)); @@ -226,13 +256,16 @@ void CoreClient::handleSessionFinished(boost::shared_ptr<Error> error) {  void CoreClient::handleNeedCredentials() {  	assert(session_);  	session_->sendCredentials(password_); +	if (options.forgetPassword) { +		purgePassword(); +	}  } -void CoreClient::handleDataRead(const std::string& data) { +void CoreClient::handleDataRead(const SafeByteArray& data) {  	onDataRead(data);  } -void CoreClient::handleDataWritten(const std::string& data) { +void CoreClient::handleDataWritten(const SafeByteArray& data) {  	onDataWritten(data);  } @@ -275,13 +308,29 @@ void CoreClient::handleStanzaAcked(Stanza::ref stanza) {  	onStanzaAcked(stanza);  } -void CoreClient::setUseStreamCompression(bool b) { -	useStreamCompression = b; +bool CoreClient::isAvailable() const { +	return stanzaChannel_->isAvailable();  } -void CoreClient::setUseTLS(UseTLS b) { -	useTLS = b; +bool CoreClient::getStreamManagementEnabled() const { +	return stanzaChannel_->getStreamManagementEnabled();  } +StanzaChannel* CoreClient::getStanzaChannel() const { +	return stanzaChannel_; +} + +const JID& CoreClient::getJID() const { +	if (session_) { +		return session_->getLocalJID(); +	} +	else { +		return jid_; +	} +} + +void CoreClient::purgePassword() { +	safeClear(password_); +}  } diff --git a/Swiften/Client/CoreClient.h b/Swiften/Client/CoreClient.h index eb9c42c..16813de 100644 --- a/Swiften/Client/CoreClient.h +++ b/Swiften/Client/CoreClient.h @@ -6,35 +6,34 @@  #pragma once -#include "Swiften/Base/boost_bsignals.h" +#include <string>  #include <boost/shared_ptr.hpp> +#include <Swiften/Base/boost_bsignals.h> -#include "Swiften/Network/PlatformDomainNameResolver.h" -#include "Swiften/Network/Connector.h" -#include "Swiften/Base/Error.h" -#include "Swiften/Client/ClientSession.h" -#include "Swiften/Client/ClientError.h" -#include "Swiften/Elements/Presence.h" -#include "Swiften/Elements/Message.h" -#include "Swiften/JID/JID.h" -#include <string> -#include "Swiften/Client/StanzaChannel.h" -#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h" -#include "Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h"  #include <Swiften/Entity/Entity.h> - -#include "Swiften/Client/ClientSessionStanzaChannel.h" +#include <Swiften/JID/JID.h> +#include <Swiften/Client/ClientError.h> +#include <Swiften/Client/ClientOptions.h> +#include <Swiften/Base/SafeByteArray.h>  namespace Swift { +	class ChainedConnector; +	class Message; +	class Presence; +	class Error;  	class IQRouter;  	class TLSContextFactory;  	class ConnectionFactory; +	class Connection;  	class TimerFactory;  	class ClientSession; +	class StanzaChannel; +	class Stanza;  	class BasicSessionStream;  	class PlatformTLSFactories;  	class CertificateTrustChecker;  	class NetworkFactories; +	class ClientSessionStanzaChannel;  	/**   	 * The central class for communicating with an XMPP server. @@ -48,16 +47,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.  			 */ -			CoreClient(const JID& jid, const std::string& password, NetworkFactories* networkFactories); +			CoreClient(const JID& jid, const SafeByteArray& password, NetworkFactories* networkFactories);  			~CoreClient();  			void setCertificate(const std::string& certificate); @@ -68,7 +62,7 @@ namespace Swift {  			 * After the connection is established, the client will set   			 * initialize the stream and authenticate.  			 */ -			void connect(); +			void connect(const ClientOptions& = ClientOptions());  			/**  			 * Disconnects the client from the server. @@ -80,12 +74,12 @@ namespace Swift {  			/**  			 * Sends a message.  			 */ -			void sendMessage(Message::ref); +			void sendMessage(boost::shared_ptr<Message>);  			/**  			 * Sends a presence stanza.  			 */ -			void sendPresence(Presence::ref); +			void sendPresence(boost::shared_ptr<Presence>);  			/**  			 * Sends raw, unchecked data. @@ -103,9 +97,7 @@ namespace Swift {  			 * Checks whether the client is connected to the server,  			 * and stanzas can be sent.  			 */ -			bool isAvailable() const { -				return stanzaChannel_->isAvailable(); -			} +			bool isAvailable() const;  			/**  			 * Checks whether the client is active. @@ -118,14 +110,7 @@ namespace Swift {  			 * Returns the JID of the client.   			 * After the session was initialized, this returns the bound JID.  			 */ -			const JID& getJID() const { -				if (session_) { -					return session_->getLocalJID(); -				} -				else { -					return jid_; -				} -			} +			const JID& getJID() const;  			/**  			 * Checks whether stream management is enabled. @@ -135,13 +120,9 @@ namespace Swift {  			 *  			 * \see onStanzaAcked  			 */ -			bool getStreamManagementEnabled() const { -				return stanzaChannel_->getStreamManagementEnabled(); -			} +			bool getStreamManagementEnabled() const; -			StanzaChannel* getStanzaChannel() const { -				return stanzaChannel_; -			} +			StanzaChannel* getStanzaChannel() const;  			/**  			 * Sets the certificate trust checker. @@ -153,16 +134,6 @@ namespace Swift {  			 */  			void setCertificateTrustChecker(CertificateTrustChecker*); -			/** -			 * Sets whether ZLib stream compression should be used when available. -			 */ -			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. @@ -184,7 +155,7 @@ namespace Swift {  			 * This signal is emitted before the XML data is parsed,  			 * so this data is unformatted.  			 */ -			boost::signal<void (const std::string&)> onDataRead; +			boost::signal<void (const SafeByteArray&)> onDataRead;  			/**  			 * Emitted when the client sends data. @@ -192,17 +163,17 @@ namespace Swift {  			 * This signal is emitted after the XML was serialized, and   			 * is unformatted.  			 */ -			boost::signal<void (const std::string&)> onDataWritten; +			boost::signal<void (const SafeByteArray&)> onDataWritten;  			/**  			 * Emitted when a message is received.  			 */ -			boost::signal<void (Message::ref)> onMessageReceived; +			boost::signal<void (boost::shared_ptr<Message>)> onMessageReceived;  			/**  			 * Emitted when a presence stanza is received.  			 */ -			boost::signal<void (Presence::ref) > onPresenceReceived; +			boost::signal<void (boost::shared_ptr<Presence>) > onPresenceReceived;  			/**  			 * Emitted when the server acknowledges receipt of a @@ -210,28 +181,34 @@ namespace Swift {  			 *  			 * \see getStreamManagementEnabled()  			 */ -			boost::signal<void (Stanza::ref)> onStanzaAcked; +			boost::signal<void (boost::shared_ptr<Stanza>)> onStanzaAcked; + +		protected: +			boost::shared_ptr<ClientSession> getSession() const { +				return session_; +			}  		private:  			void handleConnectorFinished(boost::shared_ptr<Connection>);  			void handleStanzaChannelAvailableChanged(bool available);  			void handleSessionFinished(boost::shared_ptr<Error>);  			void handleNeedCredentials(); -			void handleDataRead(const std::string&); -			void handleDataWritten(const std::string&); -			void handlePresenceReceived(Presence::ref); -			void handleMessageReceived(Message::ref); -			void handleStanzaAcked(Stanza::ref); +			void handleDataRead(const SafeByteArray&); +			void handleDataWritten(const SafeByteArray&); +			void handlePresenceReceived(boost::shared_ptr<Presence>); +			void handleMessageReceived(boost::shared_ptr<Message>); +			void handleStanzaAcked(boost::shared_ptr<Stanza>); +			void purgePassword();  		private:  			JID jid_; -			std::string password_; +			SafeByteArray password_;  			NetworkFactories* networkFactories; -			bool useStreamCompression; -			UseTLS useTLS;  			ClientSessionStanzaChannel* stanzaChannel_;  			IQRouter* iqRouter_; -			Connector::ref connector_; +			ClientOptions options; +			boost::shared_ptr<ChainedConnector> connector_; +			std::vector<ConnectionFactory*> proxyConnectionFactories;  			PlatformTLSFactories* tlsFactories;  			boost::shared_ptr<Connection> connection_;  			boost::shared_ptr<BasicSessionStream> sessionStream_; diff --git a/Swiften/Client/DummyStanzaChannel.h b/Swiften/Client/DummyStanzaChannel.h index b9f05c3..c2f3919 100644 --- a/Swiften/Client/DummyStanzaChannel.h +++ b/Swiften/Client/DummyStanzaChannel.h @@ -8,7 +8,7 @@  #include <vector> -#include "Swiften/Client/StanzaChannel.h" +#include <Swiften/Client/StanzaChannel.h>  namespace Swift {  	class DummyStanzaChannel : public StanzaChannel { @@ -56,6 +56,22 @@ namespace Swift {  				return iqStanza && iqStanza->getType() == type && iqStanza->getTo() == jid && iqStanza->getPayload<T>();  			} +			bool isResultAtIndex(size_t index, const std::string& id) { +				if (index >= sentStanzas.size()) { +					return false; +				} +				boost::shared_ptr<IQ> iqStanza = boost::dynamic_pointer_cast<IQ>(sentStanzas[index]); +				return iqStanza && iqStanza->getType() == IQ::Result && iqStanza->getID() == id; +			} + +			bool isErrorAtIndex(size_t index, const std::string& id) { +				if (index >= sentStanzas.size()) { +					return false; +				} +				boost::shared_ptr<IQ> iqStanza = boost::dynamic_pointer_cast<IQ>(sentStanzas[index]); +				return iqStanza && iqStanza->getType() == IQ::Error && iqStanza->getID() == id; +			} +  			template<typename T> boost::shared_ptr<T> getStanzaAtIndex(size_t index) {  				if (sentStanzas.size() <= index) {  					return boost::shared_ptr<T>(); diff --git a/Swiften/Client/FileStorages.cpp b/Swiften/Client/FileStorages.cpp deleted file mode 100644 index 3c76c46..0000000 --- a/Swiften/Client/FileStorages.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2010 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. - */ - -#include "Swiften/Client/FileStorages.h" -#include "Swiften/VCards/VCardFileStorage.h" -#include "Swiften/Avatars/AvatarFileStorage.h" -#include "Swiften/Disco/CapsFileStorage.h" - -namespace Swift { - -FileStorages::FileStorages(const boost::filesystem::path& baseDir, const JID& jid) { -	std::string profile = jid.toBare(); -	vcardStorage = new VCardFileStorage(baseDir / profile / "vcards"); -	capsStorage = new CapsFileStorage(baseDir / "caps"); -	avatarStorage = new AvatarFileStorage(baseDir / "avatars", baseDir / profile / "avatars"); -} - -FileStorages::~FileStorages() { -	delete avatarStorage; -	delete capsStorage; -	delete vcardStorage; -} - -VCardStorage* FileStorages::getVCardStorage() const { -	return vcardStorage; -} - -CapsStorage* FileStorages::getCapsStorage() const { -	return capsStorage; -} - -AvatarStorage* FileStorages::getAvatarStorage() const { -	return avatarStorage; -} - -} diff --git a/Swiften/Client/FileStorages.h b/Swiften/Client/FileStorages.h deleted file mode 100644 index 451105f..0000000 --- a/Swiften/Client/FileStorages.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2010 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. - */ - -#pragma once - -#include <boost/filesystem.hpp> - -#include "Swiften/Client/Storages.h" - -namespace Swift { -	class VCardFileStorage; -	class AvatarFileStorage; -	class CapsFileStorage; -	class JID; - -	/** -	 * A storages implementation that stores all controller data on disk. -	 */ -	class FileStorages : public Storages { -		public: -			/** -			 * Creates the storages interface. -			 * -			 * All data will be stored relative to a base directory, and -			 * for some controllers, in a subdirectory for the given profile. -			 * The data is stored in the following places: -			 * - Avatars: <basedir>/avatars -			 * - VCards: <basedir>/<profile>/vcards -			 * - Entity capabilities: <basedir>/caps -			 * -			 * \param baseDir the base dir to store data relative to -			 * \param jid the subdir in which profile-specific data will be stored.  -			 *   The bare JID will be used as the subdir name. -			 */ -			FileStorages(const boost::filesystem::path& baseDir, const JID& jid); -			~FileStorages(); - -			virtual VCardStorage* getVCardStorage() const; -			virtual AvatarStorage* getAvatarStorage() const; -			virtual CapsStorage* getCapsStorage() const; - -		private: -			VCardFileStorage* vcardStorage; -			AvatarFileStorage* avatarStorage; -			CapsFileStorage* capsStorage; -	}; -} diff --git a/Swiften/Client/MemoryStorages.cpp b/Swiften/Client/MemoryStorages.cpp index 5f6371b..fe171f7 100644 --- a/Swiften/Client/MemoryStorages.cpp +++ b/Swiften/Client/MemoryStorages.cpp @@ -4,10 +4,11 @@   * See Documentation/Licenses/GPLv3.txt for more information.   */ -#include "Swiften/Client/MemoryStorages.h" -#include "Swiften/VCards/VCardMemoryStorage.h" -#include "Swiften/Avatars/AvatarMemoryStorage.h" -#include "Swiften/Disco/CapsMemoryStorage.h" +#include <Swiften/Client/MemoryStorages.h> +#include <Swiften/VCards/VCardMemoryStorage.h> +#include <Swiften/Avatars/AvatarMemoryStorage.h> +#include <Swiften/Disco/CapsMemoryStorage.h> +#include <Swiften/Roster/RosterMemoryStorage.h>  namespace Swift { @@ -15,9 +16,11 @@ MemoryStorages::MemoryStorages() {  	vcardStorage = new VCardMemoryStorage();  	capsStorage = new CapsMemoryStorage();  	avatarStorage = new AvatarMemoryStorage(); +	rosterStorage = new RosterMemoryStorage();  }  MemoryStorages::~MemoryStorages() { +	delete rosterStorage;  	delete avatarStorage;  	delete capsStorage;  	delete vcardStorage; @@ -35,4 +38,9 @@ AvatarStorage* MemoryStorages::getAvatarStorage() const {  	return avatarStorage;  } +RosterStorage* MemoryStorages::getRosterStorage() const { +	return rosterStorage; +} + +  } diff --git a/Swiften/Client/MemoryStorages.h b/Swiften/Client/MemoryStorages.h index 67025cd..ca01a7a 100644 --- a/Swiften/Client/MemoryStorages.h +++ b/Swiften/Client/MemoryStorages.h @@ -6,7 +6,7 @@  #pragma once -#include "Swiften/Client/Storages.h" +#include <Swiften/Client/Storages.h>  namespace Swift {  	class VCardMemoryStorage; @@ -23,10 +23,12 @@ namespace Swift {  			virtual VCardStorage* getVCardStorage() const;  			virtual AvatarStorage* getAvatarStorage() const;  			virtual CapsStorage* getCapsStorage() const; +			virtual RosterStorage* getRosterStorage() const;  		private:  			VCardMemoryStorage* vcardStorage;  			AvatarStorage* avatarStorage;  			CapsStorage* capsStorage; +			RosterStorage* rosterStorage;  	};  } diff --git a/Swiften/Client/NickResolver.cpp b/Swiften/Client/NickResolver.cpp index 6d5e742..e6f2e41 100644 --- a/Swiften/Client/NickResolver.cpp +++ b/Swiften/Client/NickResolver.cpp @@ -4,14 +4,14 @@   * See Documentation/Licenses/GPLv3.txt for more information.   */ -#include "Swiften/Client/NickResolver.h" +#include <Swiften/Client/NickResolver.h>  #include <boost/shared_ptr.hpp>  #include <boost/bind.hpp> -#include "Swiften/MUC/MUCRegistry.h" -#include "Swiften/Roster/XMPPRoster.h" -#include "Swiften/VCards/VCardManager.h" +#include <Swiften/MUC/MUCRegistry.h> +#include <Swiften/Roster/XMPPRoster.h> +#include <Swiften/VCards/VCardManager.h>  // FIXME: The NickResolver currently relies on the vcard being requested by the client on login.  // The VCardManager should get an onConnected() signal (which is signalled when the stanzachannel is available(, and each time this is emitted, diff --git a/Swiften/Client/NickResolver.h b/Swiften/Client/NickResolver.h index 881362a..584f2ce 100644 --- a/Swiften/Client/NickResolver.h +++ b/Swiften/Client/NickResolver.h @@ -5,12 +5,12 @@   */  #include <map> -#include <boost/signals.hpp>  #include <boost/shared_ptr.hpp> +#include <Swiften/Base/boost_bsignals.h>  #include <string> -#include "Swiften/JID/JID.h" -#include "Swiften/Elements/VCard.h" +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/VCard.h>  namespace Swift {  	class XMPPRoster; diff --git a/Swiften/Client/StanzaChannel.h b/Swiften/Client/StanzaChannel.h index 4d6392c..f1d76e0 100644 --- a/Swiften/Client/StanzaChannel.h +++ b/Swiften/Client/StanzaChannel.h @@ -6,12 +6,12 @@  #pragma once -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h>  #include <boost/shared_ptr.hpp> -#include "Swiften/Queries/IQChannel.h" -#include "Swiften/Elements/Message.h" -#include "Swiften/Elements/Presence.h" +#include <Swiften/Queries/IQChannel.h> +#include <Swiften/Elements/Message.h> +#include <Swiften/Elements/Presence.h>  namespace Swift {  	class StanzaChannel : public IQChannel { diff --git a/Swiften/Client/Storages.cpp b/Swiften/Client/Storages.cpp new file mode 100644 index 0000000..3c2dbc5 --- /dev/null +++ b/Swiften/Client/Storages.cpp @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Client/Storages.h> + +using namespace Swift; + +Storages::~Storages() { +} diff --git a/Swiften/Client/Storages.h b/Swiften/Client/Storages.h index e62f0a9..1c5bbe9 100644 --- a/Swiften/Client/Storages.h +++ b/Swiften/Client/Storages.h @@ -10,6 +10,7 @@ namespace Swift {  	class VCardStorage;  	class AvatarStorage;  	class CapsStorage; +	class RosterStorage;  	/**  	 * An interface to hold storage classes for different @@ -17,10 +18,11 @@ namespace Swift {  	 */  	class Storages {  		public: -			virtual ~Storages() {} +			virtual ~Storages();  			virtual VCardStorage* getVCardStorage() const = 0;  			virtual AvatarStorage* getAvatarStorage() const = 0;  			virtual CapsStorage* getCapsStorage() const = 0; +			virtual RosterStorage* getRosterStorage() const = 0;  	};  } diff --git a/Swiften/Client/UnitTest/ClientSessionTest.cpp b/Swiften/Client/UnitTest/ClientSessionTest.cpp index 756287c..57e53e4 100644 --- a/Swiften/Client/UnitTest/ClientSessionTest.cpp +++ b/Swiften/Client/UnitTest/ClientSessionTest.cpp @@ -11,23 +11,25 @@  #include <boost/optional.hpp>  #include <boost/smart_ptr/make_shared.hpp> -#include "Swiften/Session/SessionStream.h" -#include "Swiften/Client/ClientSession.h" -#include "Swiften/Elements/StartTLSRequest.h" -#include "Swiften/Elements/StreamFeatures.h" -#include "Swiften/Elements/StreamError.h" -#include "Swiften/Elements/TLSProceed.h" -#include "Swiften/Elements/StartTLSFailure.h" -#include "Swiften/Elements/AuthRequest.h" -#include "Swiften/Elements/AuthSuccess.h" -#include "Swiften/Elements/AuthFailure.h" -#include "Swiften/Elements/StreamManagementEnabled.h" -#include "Swiften/Elements/StreamManagementFailed.h" -#include "Swiften/Elements/EnableStreamManagement.h" -#include "Swiften/Elements/IQ.h" -#include "Swiften/Elements/ResourceBind.h" -#include "Swiften/TLS/SimpleCertificate.h" -#include "Swiften/TLS/BlindCertificateTrustChecker.h" +#include <Swiften/Session/SessionStream.h> +#include <Swiften/Client/ClientSession.h> +#include <Swiften/Elements/Message.h> +#include <Swiften/Elements/StartTLSRequest.h> +#include <Swiften/Elements/StreamFeatures.h> +#include <Swiften/Elements/StreamError.h> +#include <Swiften/Elements/TLSProceed.h> +#include <Swiften/Elements/StartTLSFailure.h> +#include <Swiften/Elements/AuthRequest.h> +#include <Swiften/Elements/AuthSuccess.h> +#include <Swiften/Elements/AuthFailure.h> +#include <Swiften/Elements/StreamManagementEnabled.h> +#include <Swiften/Elements/StreamManagementFailed.h> +#include <Swiften/Elements/StanzaAck.h> +#include <Swiften/Elements/EnableStreamManagement.h> +#include <Swiften/Elements/IQ.h> +#include <Swiften/Elements/ResourceBind.h> +#include <Swiften/TLS/SimpleCertificate.h> +#include <Swiften/TLS/BlindCertificateTrustChecker.h>  using namespace Swift; @@ -45,6 +47,7 @@ class ClientSessionTest : public CppUnit::TestFixture {  		CPPUNIT_TEST(testAuthenticate_NoValidAuthMechanisms);  		CPPUNIT_TEST(testStreamManagement);  		CPPUNIT_TEST(testStreamManagement_Failed); +		CPPUNIT_TEST(testFinishAcksStanzas);  		/*  		CPPUNIT_TEST(testResourceBind);  		CPPUNIT_TEST(testResourceBind_ChangeResource); @@ -178,7 +181,7 @@ class ClientSessionTest : public CppUnit::TestFixture {  			server->sendStreamFeaturesWithPLAINAuthentication();  			CPPUNIT_ASSERT(needCredentials);  			CPPUNIT_ASSERT_EQUAL(ClientSession::WaitingForCredentials, session->getState()); -			session->sendCredentials("mypass"); +			session->sendCredentials(createSafeByteArray("mypass"));  			server->receiveAuthRequest("PLAIN");  			server->sendAuthSuccess();  			server->receiveStreamStart(); @@ -194,7 +197,7 @@ class ClientSessionTest : public CppUnit::TestFixture {  			server->sendStreamFeaturesWithPLAINAuthentication();  			CPPUNIT_ASSERT(needCredentials);  			CPPUNIT_ASSERT_EQUAL(ClientSession::WaitingForCredentials, session->getState()); -			session->sendCredentials("mypass"); +			session->sendCredentials(createSafeByteArray("mypass"));  			server->receiveAuthRequest("PLAIN");  			server->sendAuthFailure(); @@ -234,7 +237,7 @@ class ClientSessionTest : public CppUnit::TestFixture {  			server->receiveStreamStart();  			server->sendStreamStart();  			server->sendStreamFeaturesWithPLAINAuthentication(); -			session->sendCredentials("mypass"); +			session->sendCredentials(createSafeByteArray("mypass"));  			server->receiveAuthRequest("PLAIN");  			server->sendAuthSuccess();  			server->receiveStreamStart(); @@ -258,7 +261,7 @@ class ClientSessionTest : public CppUnit::TestFixture {  			server->receiveStreamStart();  			server->sendStreamStart();  			server->sendStreamFeaturesWithPLAINAuthentication(); -			session->sendCredentials("mypass"); +			session->sendCredentials(createSafeByteArray("mypass"));  			server->receiveAuthRequest("PLAIN");  			server->sendAuthSuccess();  			server->receiveStreamStart(); @@ -275,6 +278,17 @@ class ClientSessionTest : public CppUnit::TestFixture {  			session->finish();  		} +		void testFinishAcksStanzas() { +			boost::shared_ptr<ClientSession> session(createSession()); +			initializeSession(session); +			server->sendMessage(); +			server->sendMessage(); +			server->sendMessage(); + +			session->finish(); + +			server->receiveAck(3); +		}  	private:  		boost::shared_ptr<ClientSession> createSession() { @@ -285,6 +299,23 @@ class ClientSessionTest : public CppUnit::TestFixture {  			return session;  		} +		void initializeSession(boost::shared_ptr<ClientSession> session) { +			session->start(); +			server->receiveStreamStart(); +			server->sendStreamStart(); +			server->sendStreamFeaturesWithPLAINAuthentication(); +			session->sendCredentials(createSafeByteArray("mypass")); +			server->receiveAuthRequest("PLAIN"); +			server->sendAuthSuccess(); +			server->receiveStreamStart(); +			server->sendStreamStart(); +			server->sendStreamFeaturesWithBindAndStreamManagement(); +			server->receiveBind(); +			server->sendBindResult(); +			server->receiveStreamManagementEnable(); +			server->sendStreamManagementEnabled(); +		} +  		void handleSessionFinished(boost::shared_ptr<Error> error) {  			sessionFinishedReceived = true;  			sessionFinishedError = error; @@ -447,6 +478,12 @@ class ClientSessionTest : public CppUnit::TestFixture {  					onElementReceived(iq);  				} +				void sendMessage() { +					boost::shared_ptr<Message> message = boost::make_shared<Message>(); +					message->setTo(JID("foo@bar.com/bla")); +					onElementReceived(message); +				} +  				void receiveStreamStart() {  					Event event = popEvent();  					CPPUNIT_ASSERT(event.header); @@ -481,8 +518,16 @@ class ClientSessionTest : public CppUnit::TestFixture {  					bindID = iq->getID();  				} +				void receiveAck(unsigned int n) { +					Event event = popEvent(); +					CPPUNIT_ASSERT(event.element); +					boost::shared_ptr<StanzaAck> ack = boost::dynamic_pointer_cast<StanzaAck>(event.element); +					CPPUNIT_ASSERT(ack); +					CPPUNIT_ASSERT_EQUAL(n, ack->getHandledStanzasCount()); +				} +  				Event popEvent() { -					CPPUNIT_ASSERT(receivedEvents.size() > 0); +					CPPUNIT_ASSERT(!receivedEvents.empty());  					Event event = receivedEvents.front();  					receivedEvents.pop_front();  					return event; diff --git a/Swiften/Client/UnitTest/NickResolverTest.cpp b/Swiften/Client/UnitTest/NickResolverTest.cpp index bd778d4..dfc90fe 100644 --- a/Swiften/Client/UnitTest/NickResolverTest.cpp +++ b/Swiften/Client/UnitTest/NickResolverTest.cpp @@ -7,13 +7,13 @@  #include <cppunit/extensions/HelperMacros.h>  #include <cppunit/extensions/TestFactoryRegistry.h> -#include "Swiften/Client/NickResolver.h" -#include "Swiften/MUC/MUCRegistry.h" -#include "Swiften/Roster/XMPPRosterImpl.h" -#include "Swiften/VCards/VCardManager.h" -#include "Swiften/VCards/VCardMemoryStorage.h" -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/Client/DummyStanzaChannel.h" +#include <Swiften/Client/NickResolver.h> +#include <Swiften/MUC/MUCRegistry.h> +#include <Swiften/Roster/XMPPRosterImpl.h> +#include <Swiften/VCards/VCardManager.h> +#include <Swiften/VCards/VCardMemoryStorage.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Client/DummyStanzaChannel.h>  using namespace Swift; | 
 Swift
 Swift