From 497dd9b099e5810057ebcd8a3f6755819cfecdef Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Sun, 22 Nov 2009 17:46:37 +0100
Subject: Added auth success value support.


diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index 2ae110b..f05d42d 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -279,6 +279,7 @@ void MainController::handleError(const ClientError& error) {
 		case ClientError::ConnectionWriteError: message = "Error while sending data to the server"; break;
 		case ClientError::XMLError: message = "Error parsing server data"; break;
 		case ClientError::AuthenticationFailedError: message = "Login/password invalid"; break;
+		case ClientError::ServerVerificationFailedError: message = "Server verification failed"; break;
 		case ClientError::NoSupportedAuthMechanismsError: message = "Authentication mechanisms not supported"; break;
 		case ClientError::UnexpectedElementError: message = "Unexpected response"; break;
 		case ClientError::ResourceBindError: message = "Error binding resource"; break;
diff --git a/Swiften/Client/Client.cpp b/Swiften/Client/Client.cpp
index 2bd039a..874e23b 100644
--- a/Swiften/Client/Client.cpp
+++ b/Swiften/Client/Client.cpp
@@ -141,6 +141,9 @@ void Client::handleSessionFinished(boost::shared_ptr<Error> error) {
 				case ClientSession::Error::AuthenticationFailedError:
 					clientError = ClientError(ClientError::AuthenticationFailedError);
 					break;
+				case ClientSession::Error::ServerVerificationFailedError:
+					clientError = ClientError(ClientError::ServerVerificationFailedError);
+					break;
 				case ClientSession::Error::NoSupportedAuthMechanismsError:
 					clientError = ClientError(ClientError::NoSupportedAuthMechanismsError);
 					break;
diff --git a/Swiften/Client/ClientError.h b/Swiften/Client/ClientError.h
index d4f280c..55c57fc 100644
--- a/Swiften/Client/ClientError.h
+++ b/Swiften/Client/ClientError.h
@@ -11,6 +11,7 @@ namespace Swift {
 				ConnectionWriteError,
 				XMLError,
 				AuthenticationFailedError,
+				ServerVerificationFailedError,
 				NoSupportedAuthMechanismsError,
 				UnexpectedElementError,
 				ResourceBindError,
diff --git a/Swiften/Client/ClientSession.cpp b/Swiften/Client/ClientSession.cpp
index fb80754..960af70 100644
--- a/Swiften/Client/ClientSession.cpp
+++ b/Swiften/Client/ClientSession.cpp
@@ -130,14 +130,18 @@ void ClientSession::handleElement(boost::shared_ptr<Element> element) {
 			finishSession(Error::AuthenticationFailedError);
 		}
 	}
-	else if (dynamic_cast<AuthSuccess*>(element.get())) {
-		// TODO: Check success data with authenticator
+	else if (AuthSuccess* authSuccess = dynamic_cast<AuthSuccess*>(element.get())) {
 		checkState(Authenticating);
-		state = WaitingForStreamStart;
-		delete authenticator;
-		authenticator = NULL;
-		stream->resetXMPPParser();
-		sendStreamHeader();
+		if (!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;
diff --git a/Swiften/Client/ClientSession.h b/Swiften/Client/ClientSession.h
index f3bc119..5e5acbc 100644
--- a/Swiften/Client/ClientSession.h
+++ b/Swiften/Client/ClientSession.h
@@ -34,6 +34,7 @@ namespace Swift {
 			struct Error : public Swift::Error {
 				enum Type {
 					AuthenticationFailedError,
+					ServerVerificationFailedError,
 					NoSupportedAuthMechanismsError,
 					UnexpectedElementError,
 					ResourceBindError,
diff --git a/Swiften/Elements/AuthSuccess.h b/Swiften/Elements/AuthSuccess.h
index da4d798..1db1729 100644
--- a/Swiften/Elements/AuthSuccess.h
+++ b/Swiften/Elements/AuthSuccess.h
@@ -1,10 +1,22 @@
 #pragma once
 
 #include "Swiften/Elements/Element.h"
+#include "Swiften/Base/ByteArray.h"
 
 namespace Swift {
 	class AuthSuccess : public Element {
 		public:
 			AuthSuccess() {}
+
+			const ByteArray& getValue() const {
+				return value;
+			}
+
+			void setValue(const ByteArray& value) {
+				this->value = value;
+			}
+
+		private:
+			ByteArray value;
 	};
 }
diff --git a/Swiften/Parser/AuthSuccessParser.cpp b/Swiften/Parser/AuthSuccessParser.cpp
new file mode 100644
index 0000000..2dc2aa2
--- /dev/null
+++ b/Swiften/Parser/AuthSuccessParser.cpp
@@ -0,0 +1,24 @@
+#include "Swiften/Parser/AuthSuccessParser.h"
+#include "Swiften/StringCodecs/Base64.h"
+
+namespace Swift {
+
+AuthSuccessParser::AuthSuccessParser() : GenericElementParser<AuthSuccess>(), depth(0) {
+}
+
+void AuthSuccessParser::handleStartElement(const String&, const String&, const AttributeMap&) {
+	++depth;
+}
+
+void AuthSuccessParser::handleEndElement(const String&, const String&) {
+	--depth;
+	if (depth == 0) {
+		getElementGeneric()->setValue(Base64::decode(text));
+	}
+}
+
+void AuthSuccessParser::handleCharacterData(const String& text) {
+	this->text += text;
+}
+
+}
diff --git a/Swiften/Parser/AuthSuccessParser.h b/Swiften/Parser/AuthSuccessParser.h
index bb6515d..5d987c5 100644
--- a/Swiften/Parser/AuthSuccessParser.h
+++ b/Swiften/Parser/AuthSuccessParser.h
@@ -1,14 +1,20 @@
-#ifndef SWIFTEN_AUTHSUCCESSPARSER_H
-#define SWIFTEN_AUTHSUCCESSPARSER_H
+#pragma once
 
 #include "Swiften/Parser/GenericElementParser.h"
 #include "Swiften/Elements/AuthSuccess.h"
+#include "Swiften/Base/String.h"
 
 namespace Swift {
 	class AuthSuccessParser : public GenericElementParser<AuthSuccess> {
 		public:
-			AuthSuccessParser() : GenericElementParser<AuthSuccess>() {}
+			AuthSuccessParser();
+
+			virtual void handleStartElement(const String&, const String& ns, const AttributeMap&);
+			virtual void handleEndElement(const String&, const String& ns);
+			virtual void handleCharacterData(const String&);
+
+		private:
+			int depth;
+			String text;
 	};
 }
-
-#endif
diff --git a/Swiften/Parser/SConscript b/Swiften/Parser/SConscript
index d04712c..1e1dcd8 100644
--- a/Swiften/Parser/SConscript
+++ b/Swiften/Parser/SConscript
@@ -8,6 +8,7 @@ myenv.MergeFlags(swiften_env.get("EXPAT_FLAGS", ""))
 sources = [
 		"AuthRequestParser.cpp",
 		"AuthChallengeParser.cpp",
+		"AuthSuccessParser.cpp",
 		"AuthResponseParser.cpp",
 		"CompressParser.cpp",
 		"ElementParser.cpp",
diff --git a/Swiften/SConscript b/Swiften/SConscript
index 6189b2e..9742768 100644
--- a/Swiften/SConscript
+++ b/Swiften/SConscript
@@ -43,6 +43,7 @@ sources = [
 		"Roster/Roster.cpp",
 		"Roster/XMPPRoster.cpp",
 		"Serializer/AuthRequestSerializer.cpp",
+		"Serializer/AuthSuccessSerializer.cpp",
 		"Serializer/AuthChallengeSerializer.cpp",
 		"Serializer/AuthResponseSerializer.cpp",
 		"Serializer/CompressRequestSerializer.cpp",
diff --git a/Swiften/Serializer/AuthSuccessSerializer.cpp b/Swiften/Serializer/AuthSuccessSerializer.cpp
new file mode 100644
index 0000000..6d7f195
--- /dev/null
+++ b/Swiften/Serializer/AuthSuccessSerializer.cpp
@@ -0,0 +1,17 @@
+#include "Swiften/Serializer/AuthSuccessSerializer.h"
+
+#include "Swiften/Elements/AuthSuccess.h"
+#include "Swiften/StringCodecs/Base64.h"
+
+namespace Swift {
+
+AuthSuccessSerializer::AuthSuccessSerializer() {
+}
+
+String AuthSuccessSerializer::serialize(boost::shared_ptr<Element> element)  const {
+	boost::shared_ptr<AuthSuccess> authRequest(boost::dynamic_pointer_cast<AuthSuccess>(element));
+	String value = (authRequest->getValue().isEmpty() ? "=" : Base64::encode(authRequest->getValue()));
+	return "<success xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">" + value + "</challenge>";
+}
+
+}
diff --git a/Swiften/Serializer/AuthSuccessSerializer.h b/Swiften/Serializer/AuthSuccessSerializer.h
index 1fdc3ab..6ced772 100644
--- a/Swiften/Serializer/AuthSuccessSerializer.h
+++ b/Swiften/Serializer/AuthSuccessSerializer.h
@@ -1,22 +1,15 @@
-#ifndef SWIFTEN_AuthSuccessSerializer_H
-#define SWIFTEN_AuthSuccessSerializer_H
+#pragma once
 
 #include <boost/shared_ptr.hpp>
 
 #include "Swiften/Elements/AuthSuccess.h"
 #include "Swiften/Serializer/GenericElementSerializer.h"
-#include "Swiften/Serializer/XML/XMLElement.h"
 
 namespace Swift {
 	class AuthSuccessSerializer : public GenericElementSerializer<AuthSuccess> {
 		public:
-			AuthSuccessSerializer() : GenericElementSerializer<AuthSuccess>() {
-			}
+			AuthSuccessSerializer();
 
-			virtual String serialize(boost::shared_ptr<Element>) const {
-				return XMLElement("success", "urn:ietf:params:xml:ns:xmpp-sasl").serialize();
-			}
+			virtual String serialize(boost::shared_ptr<Element> element)  const;
 	};
 }
-
-#endif
-- 
cgit v0.10.2-6-g49f6