From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- extensions/auth/nsAuthSASL.cpp | 151 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 extensions/auth/nsAuthSASL.cpp (limited to 'extensions/auth/nsAuthSASL.cpp') 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 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; +} -- cgit v1.2.3