summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Client/ClientSession.cpp')
m---------Swiften0
-rw-r--r--Swiften/Client/ClientSession.cpp276
2 files changed, 0 insertions, 276 deletions
diff --git a/Swiften b/Swiften
new file mode 160000
+Subproject 8213ba16d0043d2461f4b031c881d61dda5a38c
diff --git a/Swiften/Client/ClientSession.cpp b/Swiften/Client/ClientSession.cpp
deleted file mode 100644
index 16bda40..0000000
--- a/Swiften/Client/ClientSession.cpp
+++ /dev/null
@@ -1,276 +0,0 @@
-#include "Swiften/Client/ClientSession.h"
-
-#include <boost/bind.hpp>
-
-#include "Swiften/Elements/ProtocolHeader.h"
-#include "Swiften/Elements/StreamFeatures.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/StartSession.h"
-#include "Swiften/Elements/IQ.h"
-#include "Swiften/Elements/ResourceBind.h"
-#include "Swiften/SASL/PLAINClientAuthenticator.h"
-#include "Swiften/SASL/SCRAMSHA1ClientAuthenticator.h"
-#include "Swiften/Session/SessionStream.h"
-
-namespace Swift {
-
-ClientSession::ClientSession(
- const JID& jid,
- boost::shared_ptr<SessionStream> stream) :
- localJID(jid),
- state(Initial),
- stream(stream),
- needSessionStart(false),
- authenticator(NULL) {
-}
-
-ClientSession::~ClientSession() {
-}
-
-void ClientSession::start() {
- stream->onStreamStartReceived.connect(boost::bind(&ClientSession::handleStreamStart, shared_from_this(), _1));
- stream->onElementReceived.connect(boost::bind(&ClientSession::handleElement, shared_from_this(), _1));
- stream->onError.connect(boost::bind(&ClientSession::handleStreamError, shared_from_this(), _1));
- stream->onTLSEncrypted.connect(boost::bind(&ClientSession::handleTLSEncrypted, shared_from_this()));
-
- assert(state == Initial);
- state = WaitingForStreamStart;
- sendStreamHeader();
-}
-
-void ClientSession::sendStreamHeader() {
- ProtocolHeader header;
- header.setTo(getRemoteJID());
- stream->writeHeader(header);
-}
-
-void ClientSession::sendElement(boost::shared_ptr<Element> element) {
- stream->writeElement(element);
-}
-
-void ClientSession::handleStreamStart(const ProtocolHeader&) {
- checkState(WaitingForStreamStart);
- state = Negotiating;
-}
-
-void ClientSession::handleElement(boost::shared_ptr<Element> element) {
- if (getState() == Initialized) {
- onElementReceived(element);
- }
- else if (StreamFeatures* streamFeatures = dynamic_cast<StreamFeatures*>(element.get())) {
- if (!checkState(Negotiating)) {
- return;
- }
-
- if (streamFeatures->hasStartTLS() && stream->supportsTLSEncryption()) {
- state = WaitingForEncrypt;
- stream->writeElement(boost::shared_ptr<StartTLSRequest>(new StartTLSRequest()));
- }
- else if (streamFeatures->hasCompressionMethod("zlib")) {
- state = Compressing;
- stream->writeElement(boost::shared_ptr<CompressRequest>(new CompressRequest("zlib")));
- }
- else if (streamFeatures->hasAuthenticationMechanisms()) {
- if (stream->hasTLSCertificate()) {
- if (streamFeatures->hasAuthenticationMechanism("EXTERNAL")) {
- state = Authenticating;
- stream->writeElement(boost::shared_ptr<Element>(new AuthRequest("EXTERNAL", "")));
- }
- else {
- finishSession(Error::TLSClientCertificateError);
- }
- }
- else if (streamFeatures->hasAuthenticationMechanism("SCRAM-SHA-1")) {
- // FIXME: Use a real nonce
- authenticator = new SCRAMSHA1ClientAuthenticator("ClientNonce");
- state = WaitingForCredentials;
- onNeedCredentials();
- }
- else if (streamFeatures->hasAuthenticationMechanism("PLAIN")) {
- authenticator = new PLAINClientAuthenticator();
- state = WaitingForCredentials;
- onNeedCredentials();
- }
- else {
- finishSession(Error::NoSupportedAuthMechanismsError);
- }
- }
- else {
- // Start the session
- stream->setWhitespacePingEnabled(true);
-
- if (streamFeatures->hasSession()) {
- needSessionStart = true;
- }
-
- if (streamFeatures->hasResourceBind()) {
- state = BindingResource;
- boost::shared_ptr<ResourceBind> resourceBind(new ResourceBind());
- if (!localJID.getResource().isEmpty()) {
- resourceBind->setResource(localJID.getResource());
- }
- stream->writeElement(IQ::createRequest(IQ::Set, JID(), "session-bind", resourceBind));
- }
- else if (needSessionStart) {
- sendSessionStart();
- }
- else {
- state = Initialized;
- onInitialized();
- }
- }
- }
- else if (boost::dynamic_pointer_cast<Compressed>(element)) {
- checkState(Compressing);
- state = WaitingForStreamStart;
- stream->addZLibCompression();
- stream->resetXMPPParser();
- sendStreamHeader();
- }
- else if (boost::dynamic_pointer_cast<CompressFailure>(element)) {
- finishSession(Error::CompressionFailedError);
- }
- else if (AuthChallenge* challenge = dynamic_cast<AuthChallenge*>(element.get())) {
- checkState(Authenticating);
- assert(authenticator);
- if (authenticator->setChallenge(challenge->getValue())) {
- stream->writeElement(boost::shared_ptr<AuthResponse>(new AuthResponse(authenticator->getResponse())));
- }
- else {
- finishSession(Error::AuthenticationFailedError);
- }
- }
- else if (AuthSuccess* authSuccess = dynamic_cast<AuthSuccess*>(element.get())) {
- checkState(Authenticating);
- if (authenticator && !authenticator->setChallenge(authSuccess->getValue())) {
- finishSession(Error::ServerVerificationFailedError);
- }
- else {
- state = WaitingForStreamStart;
- delete authenticator;
- authenticator = NULL;
- stream->resetXMPPParser();
- sendStreamHeader();
- }
- }
- else if (dynamic_cast<AuthFailure*>(element.get())) {
- delete authenticator;
- authenticator = NULL;
- finishSession(Error::AuthenticationFailedError);
- }
- else if (dynamic_cast<TLSProceed*>(element.get())) {
- checkState(WaitingForEncrypt);
- state = Encrypting;
- stream->addTLSEncryption();
- }
- else if (dynamic_cast<StartTLSFailure*>(element.get())) {
- finishSession(Error::TLSError);
- }
- else if (IQ* iq = dynamic_cast<IQ*>(element.get())) {
- if (state == BindingResource) {
- boost::shared_ptr<ResourceBind> resourceBind(iq->getPayload<ResourceBind>());
- if (iq->getType() == IQ::Error && iq->getID() == "session-bind") {
- finishSession(Error::ResourceBindError);
- }
- else if (!resourceBind) {
- finishSession(Error::UnexpectedElementError);
- }
- else if (iq->getType() == IQ::Result) {
- localJID = resourceBind->getJID();
- if (!localJID.isValid()) {
- finishSession(Error::ResourceBindError);
- }
- if (needSessionStart) {
- sendSessionStart();
- }
- else {
- state = Initialized;
- }
- }
- else {
- finishSession(Error::UnexpectedElementError);
- }
- }
- else if (state == StartingSession) {
- if (iq->getType() == IQ::Result) {
- state = Initialized;
- onInitialized();
- }
- else if (iq->getType() == IQ::Error) {
- finishSession(Error::SessionStartError);
- }
- else {
- finishSession(Error::UnexpectedElementError);
- }
- }
- else {
- finishSession(Error::UnexpectedElementError);
- }
- }
- else {
- // FIXME Not correct?
- state = Initialized;
- onInitialized();
- }
-}
-
-void ClientSession::sendSessionStart() {
- state = StartingSession;
- stream->writeElement(IQ::createRequest(IQ::Set, JID(), "session-start", boost::shared_ptr<StartSession>(new StartSession())));
-}
-
-bool ClientSession::checkState(State state) {
- if (state != state) {
- finishSession(Error::UnexpectedElementError);
- return false;
- }
- return true;
-}
-
-void ClientSession::sendCredentials(const String& password) {
- assert(WaitingForCredentials);
- state = Authenticating;
- authenticator->setCredentials(localJID.getNode(), password);
- stream->writeElement(boost::shared_ptr<AuthRequest>(new AuthRequest(authenticator->getName(), authenticator->getResponse())));
-}
-
-void ClientSession::handleTLSEncrypted() {
- checkState(WaitingForEncrypt);
- state = WaitingForStreamStart;
- stream->resetXMPPParser();
- sendStreamHeader();
-}
-
-void ClientSession::handleStreamError(boost::shared_ptr<Swift::Error> error) {
- finishSession(error);
-}
-
-void ClientSession::finish() {
- if (stream->isAvailable()) {
- stream->writeFooter();
- }
- finishSession(boost::shared_ptr<Error>());
-}
-
-void ClientSession::finishSession(Error::Type error) {
- finishSession(boost::shared_ptr<Swift::ClientSession::Error>(new Swift::ClientSession::Error(error)));
-}
-
-void ClientSession::finishSession(boost::shared_ptr<Swift::Error> error) {
- state = Finished;
- stream->setWhitespacePingEnabled(false);
- onFinished(error);
-}
-
-
-}