summaryrefslogtreecommitdiffstats
path: root/extensions/auth/nsAuthSASL.cpp
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /extensions/auth/nsAuthSASL.cpp
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'extensions/auth/nsAuthSASL.cpp')
-rw-r--r--extensions/auth/nsAuthSASL.cpp151
1 files changed, 151 insertions, 0 deletions
diff --git a/extensions/auth/nsAuthSASL.cpp b/extensions/auth/nsAuthSASL.cpp
new file mode 100644
index 000000000..2c72cb0ac
--- /dev/null
+++ b/extensions/auth/nsAuthSASL.cpp
@@ -0,0 +1,151 @@
+/* vim:set ts=4 sw=4 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsComponentManagerUtils.h"
+#include "nsNativeCharsetUtils.h"
+#include "nsIServiceManager.h"
+#include "nsIPrefService.h"
+
+#include "nsAuthSASL.h"
+
+static const char kNegotiateAuthSSPI[] = "network.auth.use-sspi";
+
+nsAuthSASL::nsAuthSASL()
+{
+ mSASLReady = false;
+}
+
+void nsAuthSASL::Reset()
+{
+ mSASLReady = false;
+}
+
+/* Limitations apply to this class's thread safety. See the header file */
+NS_IMPL_ISUPPORTS(nsAuthSASL, nsIAuthModule)
+
+NS_IMETHODIMP
+nsAuthSASL::Init(const char *serviceName,
+ uint32_t serviceFlags,
+ const char16_t *domain,
+ const char16_t *username,
+ const char16_t *password)
+{
+ nsresult rv;
+
+ NS_ASSERTION(username, "SASL requires a username");
+ NS_ASSERTION(!domain && !password, "unexpected credentials");
+
+ mUsername = username;
+
+ // If we're doing SASL, we should do mutual auth
+ serviceFlags |= REQ_MUTUAL_AUTH;
+
+ // Find out whether we should be trying SSPI or not
+ const char *contractID = NS_AUTH_MODULE_CONTRACTID_PREFIX "kerb-gss";
+
+ nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
+ if (prefs) {
+ bool val;
+ rv = prefs->GetBoolPref(kNegotiateAuthSSPI, &val);
+ if (NS_SUCCEEDED(rv) && val)
+ contractID = NS_AUTH_MODULE_CONTRACTID_PREFIX "kerb-sspi";
+ }
+
+ mInnerModule = do_CreateInstance(contractID, &rv);
+ // if we can't create the GSSAPI module, then bail
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ mInnerModule->Init(serviceName, serviceFlags, nullptr, nullptr, nullptr);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAuthSASL::GetNextToken(const void *inToken,
+ uint32_t inTokenLen,
+ void **outToken,
+ uint32_t *outTokenLen)
+{
+ nsresult rv;
+ void *unwrappedToken;
+ char *message;
+ uint32_t unwrappedTokenLen, messageLen;
+ nsAutoCString userbuf;
+
+ if (!mInnerModule)
+ return NS_ERROR_NOT_INITIALIZED;
+
+ if (mSASLReady) {
+ // If the server COMPLETEs with an empty token, Cyrus sends us that token.
+ // I don't think this is correct, but we need to handle that behaviour.
+ // Cyrus ignores the contents of our reply token.
+ if (inTokenLen == 0) {
+ *outToken = nullptr;
+ *outTokenLen = 0;
+ return NS_OK;
+ }
+ // We've completed the GSSAPI portion of the handshake, and are
+ // now ready to do the SASL security layer and authzid negotiation
+
+ // Input packet from the server needs to be unwrapped.
+ rv = mInnerModule->Unwrap(inToken, inTokenLen, &unwrappedToken,
+ &unwrappedTokenLen);
+ if (NS_FAILED(rv)) {
+ Reset();
+ return rv;
+ }
+
+ // If we were doing security layers then we'd care what the
+ // server had sent us. We're not, so all we had to do was make
+ // sure that the signature was correct with the above unwrap()
+ free(unwrappedToken);
+
+ NS_CopyUnicodeToNative(mUsername, userbuf);
+ messageLen = userbuf.Length() + 4 + 1;
+ message = (char *)moz_xmalloc(messageLen);
+ if (!message) {
+ Reset();
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ message[0] = 0x01; // No security layer
+ message[1] = 0x00;
+ message[2] = 0x00;
+ message[3] = 0x00; // Maxbuf must be zero if we've got no sec layer
+ strcpy(message+4, userbuf.get());
+ // Userbuf should not be nullptr terminated, so trim the trailing nullptr
+ // when wrapping the message
+ rv = mInnerModule->Wrap((void *) message, messageLen-1, false,
+ outToken, outTokenLen);
+ free(message);
+ Reset(); // All done
+ return NS_SUCCEEDED(rv) ? NS_SUCCESS_AUTH_FINISHED : rv;
+ }
+ rv = mInnerModule->GetNextToken(inToken, inTokenLen, outToken,
+ outTokenLen);
+ if (rv == NS_SUCCESS_AUTH_FINISHED) {
+ mSASLReady = true;
+ rv = NS_OK;
+ }
+ return rv;
+}
+
+NS_IMETHODIMP
+nsAuthSASL::Unwrap(const void *inToken,
+ uint32_t inTokenLen,
+ void **outToken,
+ uint32_t *outTokenLen)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsAuthSASL::Wrap(const void *inToken,
+ uint32_t inTokenLen,
+ bool confidential,
+ void **outToken,
+ uint32_t *outTokenLen)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}