From d89b27b8796f89c847c280dacfb1b09fd6cb6731 Mon Sep 17 00:00:00 2001
From: Alexey Melnikov <alexey.melnikov@isode.com>
Date: Mon, 19 Jun 2017 12:47:27 +0100
Subject: Add support for authorization identity in SASL EXTERNAL

As per RFC 4422.

Tested by connecting Harrier configured to use SASL EXTERNAL to M-Box
and verifying that authentication worked as expected.

Also added cppunit test for SASL EXTERNAL.

Change-Id: Ica5c72a858b9d8fcd9197f9c4287ca84e03fcbd2

diff --git a/Swiften/SASL/EXTERNALClientAuthenticator.cpp b/Swiften/SASL/EXTERNALClientAuthenticator.cpp
index 546140f..027bc89 100644
--- a/Swiften/SASL/EXTERNALClientAuthenticator.cpp
+++ b/Swiften/SASL/EXTERNALClientAuthenticator.cpp
@@ -12,7 +12,13 @@ EXTERNALClientAuthenticator::EXTERNALClientAuthenticator() : ClientAuthenticator
 }
 
 boost::optional<SafeByteArray> EXTERNALClientAuthenticator::getResponse() const {
-    return boost::optional<SafeByteArray>();
+    const std::string& authorizationID = getAuthorizationID();
+
+    if (authorizationID.empty()) {
+        return boost::optional<SafeByteArray>();
+    } else {
+        return createSafeByteArray(authorizationID);
+    }
 }
 
 bool EXTERNALClientAuthenticator::setChallenge(const boost::optional<ByteArray>&) {
diff --git a/Swiften/SASL/SConscript b/Swiften/SASL/SConscript
index 6aa3e72..8a248cc 100644
--- a/Swiften/SASL/SConscript
+++ b/Swiften/SASL/SConscript
@@ -23,6 +23,7 @@ swiften_env.Append(SWIFTEN_OBJECTS = [objects])
 env.Append(UNITTEST_SOURCES = [
             File("UnitTest/PLAINMessageTest.cpp"),
             File("UnitTest/PLAINClientAuthenticatorTest.cpp"),
+            File("UnitTest/EXTERNALClientAuthenticatorTest.cpp"),
             File("UnitTest/SCRAMSHA1ClientAuthenticatorTest.cpp"),
             File("UnitTest/DIGESTMD5PropertiesTest.cpp"),
             File("UnitTest/DIGESTMD5ClientAuthenticatorTest.cpp"),
diff --git a/Swiften/SASL/UnitTest/EXTERNALClientAuthenticatorTest.cpp b/Swiften/SASL/UnitTest/EXTERNALClientAuthenticatorTest.cpp
new file mode 100644
index 0000000..728eed6
--- /dev/null
+++ b/Swiften/SASL/UnitTest/EXTERNALClientAuthenticatorTest.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <QA/Checker/IO.h>
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include <Swiften/SASL/EXTERNALClientAuthenticator.h>
+
+using namespace Swift;
+
+class EXTERNALClientAuthenticatorTest : public CppUnit::TestFixture {
+        CPPUNIT_TEST_SUITE(EXTERNALClientAuthenticatorTest);
+        CPPUNIT_TEST(testGetResponse_WithoutAuthzID);
+        CPPUNIT_TEST(testGetResponse_WithAuthzID);
+        CPPUNIT_TEST_SUITE_END();
+
+    public:
+        void testGetResponse_WithoutAuthzID() {
+            EXTERNALClientAuthenticator testling;
+
+            // Authcid and password are not used (ignored)
+            testling.setCredentials("user", createSafeByteArray("pass"));
+
+            boost::optional<SafeByteArray> response = testling.getResponse();
+
+            // No data should have been returned
+            bool result = !response;
+
+            CPPUNIT_ASSERT(result);
+        }
+
+        void testGetResponse_WithAuthzID() {
+            EXTERNALClientAuthenticator testling;
+
+            // Authcid and password are not used (ignored)
+            testling.setCredentials("user", createSafeByteArray("pass"), "authz");
+
+            CPPUNIT_ASSERT_EQUAL(*testling.getResponse(), createSafeByteArray("authz", 5));
+        }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(EXTERNALClientAuthenticatorTest);
-- 
cgit v0.10.2-6-g49f6