From 4e944a225d91ff4622e50186120ef0bbbb3a1d69 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Fri, 20 Nov 2009 23:28:29 +0100
Subject: Added challenge & response parser & serializer.


diff --git a/Swiften/Elements/AuthChallenge.h b/Swiften/Elements/AuthChallenge.h
new file mode 100644
index 0000000..b8a9297
--- /dev/null
+++ b/Swiften/Elements/AuthChallenge.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include "Swiften/Base/ByteArray.h"
+#include "Swiften/Elements/Element.h"
+
+namespace Swift {
+	class AuthChallenge : public Element {
+		public:
+			AuthChallenge(const ByteArray& value = "") : value(value) {
+			}
+
+			const ByteArray& getValue() const {
+				return value;
+			}
+
+			void setValue(const ByteArray& value) {
+				this->value = value;
+			}
+
+		private:
+			ByteArray value;
+	};
+}
diff --git a/Swiften/Elements/AuthResponse.h b/Swiften/Elements/AuthResponse.h
new file mode 100644
index 0000000..8a0679f
--- /dev/null
+++ b/Swiften/Elements/AuthResponse.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include "Swiften/Base/ByteArray.h"
+#include "Swiften/Elements/Element.h"
+
+namespace Swift {
+	class AuthResponse : public Element {
+		public:
+			AuthResponse(const ByteArray& value = "") : value(value) {
+			}
+
+			const ByteArray& getValue() const {
+				return value;
+			}
+
+			void setValue(const ByteArray& value) {
+				this->value = value;
+			}
+
+		private:
+			ByteArray value;
+	};
+}
diff --git a/Swiften/Parser/AuthChallengeParser.cpp b/Swiften/Parser/AuthChallengeParser.cpp
new file mode 100644
index 0000000..c83cf7d
--- /dev/null
+++ b/Swiften/Parser/AuthChallengeParser.cpp
@@ -0,0 +1,24 @@
+#include "Swiften/Parser/AuthChallengeParser.h"
+#include "Swiften/StringCodecs/Base64.h"
+
+namespace Swift {
+
+AuthChallengeParser::AuthChallengeParser() : GenericElementParser<AuthChallenge>(), depth(0) {
+}
+
+void AuthChallengeParser::handleStartElement(const String&, const String&, const AttributeMap&) {
+	++depth;
+}
+
+void AuthChallengeParser::handleEndElement(const String&, const String&) {
+	--depth;
+	if (depth == 0) {
+		getElementGeneric()->setValue(Base64::decode(text));
+	}
+}
+
+void AuthChallengeParser::handleCharacterData(const String& text) {
+	this->text += text;
+}
+
+}
diff --git a/Swiften/Parser/AuthChallengeParser.h b/Swiften/Parser/AuthChallengeParser.h
new file mode 100644
index 0000000..be44b96
--- /dev/null
+++ b/Swiften/Parser/AuthChallengeParser.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "Swiften/Parser/GenericElementParser.h"
+#include "Swiften/Elements/AuthChallenge.h"
+#include "Swiften/Base/String.h"
+
+namespace Swift {
+	class AuthChallengeParser : public GenericElementParser<AuthChallenge> {
+		public:
+			AuthChallengeParser();
+
+			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;
+	};
+}
diff --git a/Swiften/Parser/AuthResponseParser.cpp b/Swiften/Parser/AuthResponseParser.cpp
new file mode 100644
index 0000000..b5976a5
--- /dev/null
+++ b/Swiften/Parser/AuthResponseParser.cpp
@@ -0,0 +1,24 @@
+#include "Swiften/Parser/AuthResponseParser.h"
+#include "Swiften/StringCodecs/Base64.h"
+
+namespace Swift {
+
+AuthResponseParser::AuthResponseParser() : GenericElementParser<AuthResponse>(), depth(0) {
+}
+
+void AuthResponseParser::handleStartElement(const String&, const String&, const AttributeMap&) {
+	++depth;
+}
+
+void AuthResponseParser::handleEndElement(const String&, const String&) {
+	--depth;
+	if (depth == 0) {
+		getElementGeneric()->setValue(Base64::decode(text));
+	}
+}
+
+void AuthResponseParser::handleCharacterData(const String& text) {
+	this->text += text;
+}
+
+}
diff --git a/Swiften/Parser/AuthResponseParser.h b/Swiften/Parser/AuthResponseParser.h
new file mode 100644
index 0000000..f2b3a9e
--- /dev/null
+++ b/Swiften/Parser/AuthResponseParser.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "Swiften/Parser/GenericElementParser.h"
+#include "Swiften/Elements/AuthResponse.h"
+#include "Swiften/Base/String.h"
+
+namespace Swift {
+	class AuthResponseParser : public GenericElementParser<AuthResponse> {
+		public:
+			AuthResponseParser();
+
+			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;
+	};
+}
diff --git a/Swiften/Parser/SConscript b/Swiften/Parser/SConscript
index 3330775..d04712c 100644
--- a/Swiften/Parser/SConscript
+++ b/Swiften/Parser/SConscript
@@ -7,6 +7,8 @@ myenv.MergeFlags(swiften_env.get("EXPAT_FLAGS", ""))
 
 sources = [
 		"AuthRequestParser.cpp",
+		"AuthChallengeParser.cpp",
+		"AuthResponseParser.cpp",
 		"CompressParser.cpp",
 		"ElementParser.cpp",
 		"IQParser.cpp",
diff --git a/Swiften/Parser/XMPPParser.cpp b/Swiften/Parser/XMPPParser.cpp
index f97bed8..83de263 100644
--- a/Swiften/Parser/XMPPParser.cpp
+++ b/Swiften/Parser/XMPPParser.cpp
@@ -17,6 +17,8 @@
 #include "Swiften/Parser/AuthRequestParser.h"
 #include "Swiften/Parser/AuthSuccessParser.h"
 #include "Swiften/Parser/AuthFailureParser.h"
+#include "Swiften/Parser/AuthChallengeParser.h"
+#include "Swiften/Parser/AuthResponseParser.h"
 #include "Swiften/Parser/StartTLSParser.h"
 #include "Swiften/Parser/StartTLSFailureParser.h"
 #include "Swiften/Parser/CompressParser.h"
@@ -127,6 +129,12 @@ ElementParser* XMPPParser::createElementParser(const String& element, const Stri
 	else if (element == "failure" && ns == "urn:ietf:params:xml:ns:xmpp-sasl") {
 		return new AuthFailureParser();
 	}
+	else if (element == "challenge" && ns == "urn:ietf:params:xml:ns:xmpp-sasl") {
+		return new AuthChallengeParser();
+	}
+	else if (element == "response" && ns == "urn:ietf:params:xml:ns:xmpp-sasl") {
+		return new AuthResponseParser();
+	}
 	else if (element == "starttls") {
 		return new StartTLSParser();
 	}
diff --git a/Swiften/SConscript b/Swiften/SConscript
index a5ef56d..4b7dc50 100644
--- a/Swiften/SConscript
+++ b/Swiften/SConscript
@@ -47,6 +47,8 @@ sources = [
 		"SASL/PLAINMessage.cpp",
 		"SASL/SCRAMSHA1ClientAuthenticator.cpp",
 		"Serializer/AuthRequestSerializer.cpp",
+		"Serializer/AuthChallengeSerializer.cpp",
+		"Serializer/AuthResponseSerializer.cpp",
 		"Serializer/CompressRequestSerializer.cpp",
 		"Serializer/ElementSerializer.cpp",
 		"Serializer/MessageSerializer.cpp",
diff --git a/Swiften/Serializer/AuthChallengeSerializer.cpp b/Swiften/Serializer/AuthChallengeSerializer.cpp
new file mode 100644
index 0000000..152607d
--- /dev/null
+++ b/Swiften/Serializer/AuthChallengeSerializer.cpp
@@ -0,0 +1,17 @@
+#include "Swiften/Serializer/AuthChallengeSerializer.h"
+
+#include "Swiften/Elements/AuthChallenge.h"
+#include "Swiften/StringCodecs/Base64.h"
+
+namespace Swift {
+
+AuthChallengeSerializer::AuthChallengeSerializer() {
+}
+
+String AuthChallengeSerializer::serialize(boost::shared_ptr<Element> element)  const {
+	boost::shared_ptr<AuthChallenge> authRequest(boost::dynamic_pointer_cast<AuthChallenge>(element));
+	String value = (authRequest->getValue().isEmpty() ? "=" : Base64::encode(authRequest->getValue()));
+	return "<challenge xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">" + value + "</challenge>";
+}
+
+}
diff --git a/Swiften/Serializer/AuthChallengeSerializer.h b/Swiften/Serializer/AuthChallengeSerializer.h
new file mode 100644
index 0000000..010d9a9
--- /dev/null
+++ b/Swiften/Serializer/AuthChallengeSerializer.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+
+#include "Swiften/Elements/AuthChallenge.h"
+#include "Swiften/Serializer/GenericElementSerializer.h"
+
+namespace Swift {
+	class AuthChallengeSerializer : public GenericElementSerializer<AuthChallenge> {
+		public:
+			AuthChallengeSerializer();
+
+			virtual String serialize(boost::shared_ptr<Element> element)  const;
+	};
+}
diff --git a/Swiften/Serializer/AuthResponseSerializer.cpp b/Swiften/Serializer/AuthResponseSerializer.cpp
new file mode 100644
index 0000000..2348a3d
--- /dev/null
+++ b/Swiften/Serializer/AuthResponseSerializer.cpp
@@ -0,0 +1,17 @@
+#include "Swiften/Serializer/AuthResponseSerializer.h"
+
+#include "Swiften/Elements/AuthResponse.h"
+#include "Swiften/StringCodecs/Base64.h"
+
+namespace Swift {
+
+AuthResponseSerializer::AuthResponseSerializer() {
+}
+
+String AuthResponseSerializer::serialize(boost::shared_ptr<Element> element)  const {
+	boost::shared_ptr<AuthResponse> authRequest(boost::dynamic_pointer_cast<AuthResponse>(element));
+	String value = (authRequest->getValue().isEmpty() ? "=" : Base64::encode(authRequest->getValue()));
+	return "<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">" + value + "</response>";
+}
+
+}
diff --git a/Swiften/Serializer/AuthResponseSerializer.h b/Swiften/Serializer/AuthResponseSerializer.h
new file mode 100644
index 0000000..8d47291
--- /dev/null
+++ b/Swiften/Serializer/AuthResponseSerializer.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+
+#include "Swiften/Elements/AuthResponse.h"
+#include "Swiften/Serializer/GenericElementSerializer.h"
+
+namespace Swift {
+	class AuthResponseSerializer : public GenericElementSerializer<AuthResponse> {
+		public:
+			AuthResponseSerializer();
+
+			virtual String serialize(boost::shared_ptr<Element> element)  const;
+	};
+}
diff --git a/Swiften/Serializer/XMPPSerializer.cpp b/Swiften/Serializer/XMPPSerializer.cpp
index 660bb37..082cdf3 100644
--- a/Swiften/Serializer/XMPPSerializer.cpp
+++ b/Swiften/Serializer/XMPPSerializer.cpp
@@ -11,6 +11,8 @@
 #include "Swiften/Serializer/AuthRequestSerializer.h"
 #include "Swiften/Serializer/AuthFailureSerializer.h"
 #include "Swiften/Serializer/AuthSuccessSerializer.h"
+#include "Swiften/Serializer/AuthChallengeSerializer.h"
+#include "Swiften/Serializer/AuthResponseSerializer.h"
 #include "Swiften/Serializer/StartTLSRequestSerializer.h"
 #include "Swiften/Serializer/StartTLSFailureSerializer.h"
 #include "Swiften/Serializer/TLSProceedSerializer.h"
@@ -29,6 +31,8 @@ XMPPSerializer::XMPPSerializer(PayloadSerializerCollection* payloadSerializers)
 	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new AuthRequestSerializer()));
 	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new AuthFailureSerializer()));
 	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new AuthSuccessSerializer()));
+	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new AuthChallengeSerializer()));
+	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new AuthResponseSerializer()));
 	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new StartTLSRequestSerializer()));
 	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new StartTLSFailureSerializer()));
 	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new TLSProceedSerializer()));
-- 
cgit v0.10.2-6-g49f6