diff options
Diffstat (limited to 'Swiften/Client/ClientSession.cpp')
-rw-r--r-- | Swiften/Client/ClientSession.cpp | 105 |
1 files changed, 58 insertions, 47 deletions
diff --git a/Swiften/Client/ClientSession.cpp b/Swiften/Client/ClientSession.cpp index e1c1d8e..791ee75 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 { @@ -51,9 +52,11 @@ ClientSession::ClientSession( allowPLAINOverNonTLS(false), useStreamCompression(true), useTLS(UseTLSWhenAvailable), + useAcks(true), needSessionStart(false), needResourceBind(false), needAcking(false), + rosterVersioningSupported(false), authenticator(NULL), certificateTrustChecker(NULL) { } @@ -173,17 +176,20 @@ 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 (useTLS == RequireTLS && !stream->isTLSEncrypted()) { + finishSession(Error::NoSupportedAuthMechanismsError); } 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 +197,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,10 +229,11 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) { } else { // Start the session + rosterVersioningSupported = streamFeatures->hasRosterVersioning(); stream->setWhitespacePingEnabled(true); needSessionStart = streamFeatures->hasSession(); needResourceBind = streamFeatures->hasResourceBind(); - needAcking = streamFeatures->hasStreamManagement(); + needAcking = streamFeatures->hasStreamManagement() && useAcks; if (!needResourceBind) { // Resource binding is a MUST finishSession(Error::ResourceBindError); @@ -247,10 +254,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 +270,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 +279,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 +314,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 +322,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 +342,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 +363,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 +415,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 +438,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)); } } |