summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Client/ClientSession.cpp')
-rw-r--r--Swiften/Client/ClientSession.cpp105
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));
}
}