firefox/mozilla-890908-async-nego.patch
2016-09-08 13:37:25 +02:00

758 lines
31 KiB
Diff

diff -up firefox-48.0/extensions/auth/nsHttpNegotiateAuth.cpp.890908-async-nego firefox-48.0/extensions/auth/nsHttpNegotiateAuth.cpp
--- firefox-48.0/extensions/auth/nsHttpNegotiateAuth.cpp.890908-async-nego 2016-07-25 22:22:05.000000000 +0200
+++ firefox-48.0/extensions/auth/nsHttpNegotiateAuth.cpp 2016-07-27 09:56:55.652261702 +0200
@@ -40,6 +40,10 @@
#include "mozilla/Snprintf.h"
#include "nsIChannel.h"
#include "nsNetUtil.h"
+#include "nsThreadUtils.h"
+#include "nsIHttpAuthenticatorCallback.h"
+#include "mozilla/Mutex.h"
+#include "nsICancelable.h"
//-----------------------------------------------------------------------------
@@ -51,6 +55,7 @@ static const char kNegotiateAuthAllowNon
static const char kNegotiateAuthSSPI[] = "network.auth.use-sspi";
#define kNegotiateLen (sizeof(kNegotiate)-1)
+#define DEFAULT_THREAD_TIMEOUT_MS 30000
//-----------------------------------------------------------------------------
@@ -184,7 +189,260 @@ nsHttpNegotiateAuth::ChallengeReceived(n
}
NS_IMPL_ISUPPORTS(nsHttpNegotiateAuth, nsIHttpAuthenticator)
-
+
+namespace {
+
+//
+// GetNextTokenCompleteEvent
+//
+// This event is fired on main thread when async call of
+// nsHttpNegotiateAuth::GenerateCredentials is finished. During the Run()
+// method the nsIHttpAuthenticatorCallback::OnCredsAvailable is called with
+// obtained credentials, flags and NS_OK when successful, otherwise
+// NS_ERROR_FAILURE is returned as a result of failed operation.
+//
+class GetNextTokenCompleteEvent final : public nsIRunnable,
+ public nsICancelable
+{
+ virtual ~GetNextTokenCompleteEvent()
+ {
+ if (mCreds) {
+ free(mCreds);
+ }
+ };
+
+public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+
+ explicit GetNextTokenCompleteEvent(nsIHttpAuthenticatorCallback* aCallback)
+ : mCallback(aCallback)
+ , mCreds(nullptr)
+ , mCancelled(false)
+ {
+ }
+
+ NS_IMETHODIMP DispatchSuccess(char *aCreds,
+ uint32_t aFlags,
+ already_AddRefed<nsISupports> aSessionState,
+ already_AddRefed<nsISupports> aContinuationState)
+ {
+ // Called from worker thread
+ MOZ_ASSERT(!NS_IsMainThread());
+
+ mCreds = aCreds;
+ mFlags = aFlags;
+ mResult = NS_OK;
+ mSessionState = aSessionState;
+ mContinuationState = aContinuationState;
+ return NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL);
+ }
+
+ NS_IMETHODIMP DispatchError(already_AddRefed<nsISupports> aSessionState,
+ already_AddRefed<nsISupports> aContinuationState)
+ {
+ // Called from worker thread
+ MOZ_ASSERT(!NS_IsMainThread());
+
+ mResult = NS_ERROR_FAILURE;
+ mSessionState = aSessionState;
+ mContinuationState = aContinuationState;
+ return NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL);
+ }
+
+ NS_IMETHODIMP Run() override
+ {
+ // Runs on main thread
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (!mCancelled) {
+ nsCOMPtr<nsIHttpAuthenticatorCallback> callback;
+ callback.swap(mCallback);
+ callback->OnCredsGenerated(mCreds, mFlags, mResult, mSessionState, mContinuationState);
+ }
+ return NS_OK;
+ }
+
+ NS_IMETHODIMP Cancel(nsresult aReason) override
+ {
+ // Supposed to be called from main thread
+ MOZ_ASSERT(NS_IsMainThread());
+
+ mCancelled = true;
+ return NS_OK;
+ }
+
+private:
+ nsCOMPtr<nsIHttpAuthenticatorCallback> mCallback;
+ char *mCreds; // This class owns it, freed in destructor
+ uint32_t mFlags;
+ nsresult mResult;
+ bool mCancelled;
+ nsCOMPtr<nsISupports> mSessionState;
+ nsCOMPtr<nsISupports> mContinuationState;
+};
+
+NS_IMPL_ISUPPORTS(GetNextTokenCompleteEvent, nsIRunnable, nsICancelable)
+
+//
+// GetNextTokenRunnable
+//
+// This runnable is created by GenerateCredentialsAsync and it runs
+// in nsHttpNegotiateAuth::mNegotiateThread and calling GenerateCredentials.
+//
+class GetNextTokenRunnable final : public mozilla::Runnable
+{
+ virtual ~GetNextTokenRunnable() {}
+ public:
+ GetNextTokenRunnable(nsIHttpAuthenticableChannel *authChannel,
+ const char *challenge,
+ bool isProxyAuth,
+ const char16_t *domain,
+ const char16_t *username,
+ const char16_t *password,
+ nsISupports *sessionState,
+ nsISupports *continuationState,
+ GetNextTokenCompleteEvent *aCompleteEvent
+ )
+ : mAuthChannel(authChannel)
+ , mChallenge(challenge)
+ , mIsProxyAuth(isProxyAuth)
+ , mDomain(domain)
+ , mUsername(username)
+ , mPassword(password)
+ , mSessionState(sessionState)
+ , mContinuationState(continuationState)
+ , mCompleteEvent(aCompleteEvent)
+ {
+ }
+
+ NS_IMETHODIMP Run() override
+ {
+ // Runs on worker thread
+ MOZ_ASSERT(!NS_IsMainThread());
+
+ char *creds;
+ uint32_t flags;
+ nsresult rv = ObtainCredentialsAndFlags(&creds, &flags);
+
+ // Passing session and continuation state this way to not touch
+ // referencing of the object that may not be thread safe.
+ // Not having a thread safe referencing doesn't mean the object
+ // cannot be used on multiple threads (one example is nsAuthSSPI.)
+ // This ensures state objects will be destroyed on the main thread
+ // when not changed by GenerateCredentials.
+ if (NS_FAILED(rv)) {
+ return mCompleteEvent->DispatchError(mSessionState.forget(),
+ mContinuationState.forget());
+ }
+
+ return mCompleteEvent->DispatchSuccess(creds, flags,
+ mSessionState.forget(),
+ mContinuationState.forget());
+ }
+
+ NS_IMETHODIMP ObtainCredentialsAndFlags(char **aCreds, uint32_t *aFlags)
+ {
+ nsresult rv;
+
+ // Use negotiate service to call GenerateCredentials outside of main thread
+ nsAutoCString contractId;
+ contractId.Assign(NS_HTTP_AUTHENTICATOR_CONTRACTID_PREFIX);
+ contractId.Append("negotiate");
+ nsCOMPtr<nsIHttpAuthenticator> authenticator =
+ do_GetService(contractId.get(), &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsISupports *sessionState = mSessionState;
+ nsISupports *continuationState = mContinuationState;
+ // The continuationState is for the sake of completeness propagated
+ // to the caller (despite it is not changed in any GenerateCredentials
+ // implementation).
+ //
+ // The only implementation that use sessionState is the
+ // nsHttpDigestAuth::GenerateCredentials. Since there's no reason
+ // to implement nsHttpDigestAuth::GenerateCredentialsAsync
+ // because digest auth does not block the main thread, we won't
+ // propagate changes to sessionState to the caller because of
+ // the change is too complicated on the caller side.
+ //
+ // Should any of the session or continuation states change inside
+ // this method, they must be threadsafe.
+ rv = authenticator->GenerateCredentials(mAuthChannel,
+ mChallenge.get(),
+ mIsProxyAuth,
+ mDomain.get(),
+ mUsername.get(),
+ mPassword.get(),
+ &sessionState,
+ &continuationState,
+ aFlags,
+ aCreds);
+ if (mSessionState != sessionState) {
+ mSessionState = sessionState;
+ }
+ if (mContinuationState != continuationState) {
+ mContinuationState = continuationState;
+ }
+ return rv;
+ }
+ private:
+ nsCOMPtr<nsIHttpAuthenticableChannel> mAuthChannel;
+ nsCString mChallenge;
+ bool mIsProxyAuth;
+ nsString mDomain;
+ nsString mUsername;
+ nsString mPassword;
+ nsCOMPtr<nsISupports> mSessionState;
+ nsCOMPtr<nsISupports> mContinuationState;
+ RefPtr<GetNextTokenCompleteEvent> mCompleteEvent;
+};
+
+} // anonymous namespace
+
+NS_IMETHODIMP
+nsHttpNegotiateAuth::GenerateCredentialsAsync(nsIHttpAuthenticableChannel *authChannel,
+ nsIHttpAuthenticatorCallback* aCallback,
+ const char *challenge,
+ bool isProxyAuth,
+ const char16_t *domain,
+ const char16_t *username,
+ const char16_t *password,
+ nsISupports *sessionState,
+ nsISupports *continuationState,
+ nsICancelable **aCancelable)
+{
+ NS_ENSURE_ARG(aCallback);
+ NS_ENSURE_ARG_POINTER(aCancelable);
+
+ RefPtr<GetNextTokenCompleteEvent> cancelEvent =
+ new GetNextTokenCompleteEvent(aCallback);
+
+
+ nsCOMPtr<nsIRunnable> getNextTokenRunnable =
+ new GetNextTokenRunnable(authChannel,
+ challenge,
+ isProxyAuth,
+ domain,
+ username,
+ password,
+ sessionState,
+ continuationState,
+ cancelEvent);
+ cancelEvent.forget(aCancelable);
+
+ nsresult rv;
+ if (!mNegotiateThread) {
+ mNegotiateThread =
+ new mozilla::LazyIdleThread(DEFAULT_THREAD_TIMEOUT_MS,
+ NS_LITERAL_CSTRING("NegotiateAuth"));
+ NS_ENSURE_TRUE(mNegotiateThread, NS_ERROR_OUT_OF_MEMORY);
+ }
+ rv = mNegotiateThread->Dispatch(getNextTokenRunnable, NS_DISPATCH_NORMAL);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return NS_OK;
+}
+
//
// GenerateCredentials
//
diff -up firefox-48.0/extensions/auth/nsHttpNegotiateAuth.h.890908-async-nego firefox-48.0/extensions/auth/nsHttpNegotiateAuth.h
--- firefox-48.0/extensions/auth/nsHttpNegotiateAuth.h.890908-async-nego 2016-05-12 19:13:34.000000000 +0200
+++ firefox-48.0/extensions/auth/nsHttpNegotiateAuth.h 2016-07-27 09:56:55.652261702 +0200
@@ -10,6 +10,7 @@
#include "nsIURI.h"
#include "nsSubstring.h"
#include "mozilla/Attributes.h"
+#include "mozilla/LazyIdleThread.h"
// The nsHttpNegotiateAuth class provides responses for the GSS-API Negotiate method
// as specified by Microsoft in draft-brezak-spnego-http-04.txt
@@ -17,7 +18,7 @@
class nsHttpNegotiateAuth final : public nsIHttpAuthenticator
{
public:
- NS_DECL_ISUPPORTS
+ NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIHTTPAUTHENTICATOR
private:
@@ -37,5 +38,7 @@ private:
int32_t port,
const char *baseStart,
const char *baseEnd);
+ // Thread for GenerateCredentialsAsync
+ RefPtr<mozilla::LazyIdleThread> mNegotiateThread;
};
#endif /* nsHttpNegotiateAuth_h__ */
diff -up firefox-48.0/netwerk/base/moz.build.890908-async-nego firefox-48.0/netwerk/base/moz.build
--- firefox-48.0/netwerk/base/moz.build.890908-async-nego 2016-07-25 22:22:05.000000000 +0200
+++ firefox-48.0/netwerk/base/moz.build 2016-07-27 09:56:55.653261702 +0200
@@ -48,6 +48,7 @@ XPIDL_SOURCES += [
'nsIFileURL.idl',
'nsIForcePendingChannel.idl',
'nsIFormPOSTActionChannel.idl',
+ 'nsIHttpAuthenticatorCallback.idl',
'nsIHttpPushListener.idl',
'nsIIncrementalDownload.idl',
'nsIIncrementalStreamLoader.idl',
diff -up firefox-48.0/netwerk/base/nsIHttpAuthenticatorCallback.idl.890908-async-nego firefox-48.0/netwerk/base/nsIHttpAuthenticatorCallback.idl
--- firefox-48.0/netwerk/base/nsIHttpAuthenticatorCallback.idl.890908-async-nego 2016-07-27 09:56:55.653261702 +0200
+++ firefox-48.0/netwerk/base/nsIHttpAuthenticatorCallback.idl 2016-07-27 09:56:55.653261702 +0200
@@ -0,0 +1,31 @@
+/* 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 "nsISupports.idl"
+
+[scriptable, uuid(d989cb03-e446-4086-b9e6-46842cb97bd5)]
+interface nsIHttpAuthenticatorCallback : nsISupports
+{
+ /**
+ * Authentication data for a header is available.
+ *
+ * @param aCreds
+ * Credentials which were obtained asynchonously.
+ * @param aFlags
+ * Flags set by asynchronous call.
+ * @param aResult
+ * Result status of credentials generation
+ * @param aSessionState
+ * Modified session state to be passed to caller
+ * @param aContinuationState
+ * Modified continuation state to be passed to caller
+ */
+ void onCredsGenerated(in string aCreds,
+ in unsigned long aFlags,
+ in nsresult aResult,
+ in nsISupports aSessionsState,
+ in nsISupports aContinuationState);
+
+};
+
diff -up firefox-48.0/netwerk/protocol/http/nsHttpBasicAuth.cpp.890908-async-nego firefox-48.0/netwerk/protocol/http/nsHttpBasicAuth.cpp
--- firefox-48.0/netwerk/protocol/http/nsHttpBasicAuth.cpp.890908-async-nego 2016-05-12 19:13:28.000000000 +0200
+++ firefox-48.0/netwerk/protocol/http/nsHttpBasicAuth.cpp 2016-07-27 09:56:55.653261702 +0200
@@ -49,6 +49,20 @@ nsHttpBasicAuth::ChallengeReceived(nsIHt
*identityInvalid = true;
return NS_OK;
}
+NS_IMETHODIMP
+nsHttpBasicAuth::GenerateCredentialsAsync(nsIHttpAuthenticableChannel *authChannel,
+ nsIHttpAuthenticatorCallback* aCallback,
+ const char *challenge,
+ bool isProxyAuth,
+ const char16_t *domain,
+ const char16_t *username,
+ const char16_t *password,
+ nsISupports *sessionState,
+ nsISupports *continuationState,
+ nsICancelable **aCancellable)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
NS_IMETHODIMP
nsHttpBasicAuth::GenerateCredentials(nsIHttpAuthenticableChannel *authChannel,
diff -up firefox-48.0/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp.890908-async-nego firefox-48.0/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp
--- firefox-48.0/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp.890908-async-nego 2016-05-12 19:13:28.000000000 +0200
+++ firefox-48.0/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp 2016-07-27 09:56:55.653261702 +0200
@@ -267,6 +267,11 @@ nsHttpChannelAuthProvider::Cancel(nsresu
mAsyncPromptAuthCancelable->Cancel(status);
mAsyncPromptAuthCancelable = nullptr;
}
+
+ if (mGenerateCredentialsCancelable) {
+ mGenerateCredentialsCancelable->Cancel(status);
+ mGenerateCredentialsCancelable = nullptr;
+ }
return NS_OK;
}
@@ -280,6 +285,11 @@ nsHttpChannelAuthProvider::Disconnect(ns
mAsyncPromptAuthCancelable = nullptr;
}
+ if (mGenerateCredentialsCancelable) {
+ mGenerateCredentialsCancelable->Cancel(status);
+ mGenerateCredentialsCancelable = nullptr;
+ }
+
NS_IF_RELEASE(mProxyAuthContinuationState);
NS_IF_RELEASE(mAuthContinuationState);
@@ -355,11 +365,6 @@ nsHttpChannelAuthProvider::GenCredsAndSe
char **result)
{
nsresult rv;
- uint32_t authFlags;
-
- rv = auth->GetAuthFlags(&authFlags);
- if (NS_FAILED(rv)) return rv;
-
nsISupports *ss = sessionState;
// set informations that depend on whether
@@ -373,6 +378,22 @@ nsHttpChannelAuthProvider::GenCredsAndSe
continuationState = &mAuthContinuationState;
}
+ rv = auth->GenerateCredentialsAsync(mAuthChannel,
+ this,
+ challenge,
+ proxyAuth,
+ ident.Domain(),
+ ident.User(),
+ ident.Password(),
+ ss,
+ *continuationState,
+ getter_AddRefs(mGenerateCredentialsCancelable));
+ if (NS_SUCCEEDED(rv)) {
+ // Calling generate credentials async, results will be dispatched to the
+ // main thread by calling OnCredsGenerated method
+ return NS_ERROR_IN_PROGRESS;
+ }
+
uint32_t generateFlags;
rv = auth->GenerateCredentials(mAuthChannel,
challenge,
@@ -393,6 +414,29 @@ nsHttpChannelAuthProvider::GenCredsAndSe
LOG(("generated creds: %s\n", *result));
#endif
+ return UpdateCache(auth, scheme, host, port, directory, realm,
+ challenge, ident, *result, generateFlags, sessionState);
+}
+
+nsresult
+nsHttpChannelAuthProvider::UpdateCache(nsIHttpAuthenticator *auth,
+ const char *scheme,
+ const char *host,
+ int32_t port,
+ const char *directory,
+ const char *realm,
+ const char *challenge,
+ const nsHttpAuthIdentity &ident,
+ const char *creds,
+ uint32_t generateFlags,
+ nsISupports *sessionState)
+{
+ nsresult rv;
+
+ uint32_t authFlags;
+ rv = auth->GetAuthFlags(&authFlags);
+ if (NS_FAILED(rv)) return rv;
+
// find out if this authenticator allows reuse of credentials and/or
// challenge.
bool saveCreds =
@@ -410,6 +454,7 @@ nsHttpChannelAuthProvider::GenCredsAndSe
nsAutoCString suffix;
GetOriginAttributesSuffix(chan, suffix);
+
// create a cache entry. we do this even though we don't yet know that
// these credentials are valid b/c we need to avoid prompting the user
// more than once in case the credentials are valid.
@@ -417,12 +462,13 @@ nsHttpChannelAuthProvider::GenCredsAndSe
// if the credentials are not reusable, then we don't bother sticking
// them in the auth cache.
rv = authCache->SetAuthEntry(scheme, host, port, directory, realm,
- saveCreds ? *result : nullptr,
+ saveCreds ? creds : nullptr,
saveChallenge ? challenge : nullptr,
suffix,
saveIdentity ? &ident : nullptr,
sessionState);
return rv;
+
}
nsresult
@@ -1223,6 +1269,63 @@ NS_IMETHODIMP nsHttpChannelAuthProvider:
return NS_OK;
}
+NS_IMETHODIMP nsHttpChannelAuthProvider::OnCredsGenerated(const char *aGeneratedCreds,
+ uint32_t aFlags,
+ nsresult aResult,
+ nsISupports* aSessionState,
+ nsISupports* aContinuationState)
+{
+ nsresult rv;
+
+ MOZ_ASSERT(NS_IsMainThread());
+
+ // When channel is closed, do not proceed
+ if (!mAuthChannel) {
+ return NS_OK;
+ }
+
+ mGenerateCredentialsCancelable = nullptr;
+
+ if (NS_FAILED(aResult)) {
+ return OnAuthCancelled(nullptr, true);
+ }
+
+ // We want to update m(Proxy)AuthContinuationState in case it was changed by
+ // nsHttpNegotiateAuth::GenerateCredentials
+ nsCOMPtr<nsISupports> contState(aContinuationState);
+ if (mProxyAuth) {
+ contState.swap(mProxyAuthContinuationState);
+ } else {
+ contState.swap(mAuthContinuationState);
+ }
+
+ nsCOMPtr<nsIHttpAuthenticator> auth;
+ nsAutoCString unused;
+ rv = GetAuthenticator(mCurrentChallenge.get(), unused, getter_AddRefs(auth));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ const char *host;
+ int32_t port;
+ nsHttpAuthIdentity *ident;
+ nsAutoCString directory, scheme;
+ nsISupports **unusedContinuationState;
+
+ // Get realm from challenge
+ nsAutoCString realm;
+ ParseRealm(mCurrentChallenge.get(), realm);
+
+ rv = GetAuthorizationMembers(mProxyAuth, scheme, host, port,
+ directory, ident, unusedContinuationState);
+ if (NS_FAILED(rv)) return rv;
+
+ UpdateCache(auth, scheme.get(), host, port, directory.get(), realm.get(),
+ mCurrentChallenge.get(), *ident, aGeneratedCreds, aFlags, aSessionState);
+ mCurrentChallenge.Truncate();
+
+ ContinueOnAuthAvailable(nsDependentCString(aGeneratedCreds));
+ return NS_OK;
+}
+
nsresult
nsHttpChannelAuthProvider::ContinueOnAuthAvailable(const nsCSubstring& creds)
{
@@ -1457,7 +1560,7 @@ nsHttpChannelAuthProvider::GetCurrentPat
}
NS_IMPL_ISUPPORTS(nsHttpChannelAuthProvider, nsICancelable,
- nsIHttpChannelAuthProvider, nsIAuthPromptCallback)
+ nsIHttpChannelAuthProvider, nsIAuthPromptCallback, nsIHttpAuthenticatorCallback)
} // namespace net
} // namespace mozilla
diff -up firefox-48.0/netwerk/protocol/http/nsHttpChannelAuthProvider.h.890908-async-nego firefox-48.0/netwerk/protocol/http/nsHttpChannelAuthProvider.h
--- firefox-48.0/netwerk/protocol/http/nsHttpChannelAuthProvider.h.890908-async-nego 2016-05-12 19:13:28.000000000 +0200
+++ firefox-48.0/netwerk/protocol/http/nsHttpChannelAuthProvider.h 2016-07-27 09:57:34.084262023 +0200
@@ -9,11 +9,13 @@
#include "nsIHttpChannelAuthProvider.h"
#include "nsIAuthPromptCallback.h"
+#include "nsIHttpAuthenticatorCallback.h"
#include "nsString.h"
#include "nsCOMPtr.h"
#include "nsHttpAuthCache.h"
#include "nsProxyInfo.h"
#include "nsCRT.h"
+#include "nsICancelableRunnable.h"
class nsIHttpAuthenticableChannel;
class nsIHttpAuthenticator;
@@ -25,12 +27,14 @@ class nsHttpHandler;
class nsHttpChannelAuthProvider : public nsIHttpChannelAuthProvider
, public nsIAuthPromptCallback
+ , public nsIHttpAuthenticatorCallback
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSICANCELABLE
NS_DECL_NSIHTTPCHANNELAUTHPROVIDER
NS_DECL_NSIAUTHPROMPTCALLBACK
+ NS_DECL_NSIHTTPAUTHENTICATORCALLBACK
nsHttpChannelAuthProvider();
static void InitializePrefs();
@@ -117,6 +121,19 @@ private:
// For more details look at the bug 647010.
bool BlockPrompt();
+ // Store credentials to the cache when appropriate aFlags are set.
+ nsresult UpdateCache(nsIHttpAuthenticator *aAuth,
+ const char *aScheme,
+ const char *aHost,
+ int32_t aPort,
+ const char *aDirectory,
+ const char *aRealm,
+ const char *aChallenge,
+ const nsHttpAuthIdentity &aIdent,
+ const char *aCreds,
+ uint32_t aGenerateFlags,
+ nsISupports *aSessionState);
+
private:
nsIHttpAuthenticableChannel *mAuthChannel; // weak ref
@@ -160,6 +177,7 @@ private:
// authentication credentials dialogs for sub-resources and cross-origin
// sub-resources.
static uint32_t sAuthAllowPref;
+ nsCOMPtr<nsICancelable> mGenerateCredentialsCancelable;
};
} // namespace net
diff -up firefox-48.0/netwerk/protocol/http/nsHttpDigestAuth.cpp.890908-async-nego firefox-48.0/netwerk/protocol/http/nsHttpDigestAuth.cpp
--- firefox-48.0/netwerk/protocol/http/nsHttpDigestAuth.cpp.890908-async-nego 2016-05-12 19:13:28.000000000 +0200
+++ firefox-48.0/netwerk/protocol/http/nsHttpDigestAuth.cpp 2016-07-27 09:56:55.654261702 +0200
@@ -158,6 +158,22 @@ nsHttpDigestAuth::ChallengeReceived(nsIH
return NS_OK;
}
+
+NS_IMETHODIMP
+nsHttpDigestAuth::GenerateCredentialsAsync(nsIHttpAuthenticableChannel *authChannel,
+ nsIHttpAuthenticatorCallback* aCallback,
+ const char *challenge,
+ bool isProxyAuth,
+ const char16_t *domain,
+ const char16_t *username,
+ const char16_t *password,
+ nsISupports *sessionState,
+ nsISupports *continuationState,
+ nsICancelable **aCancellable)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
NS_IMETHODIMP
nsHttpDigestAuth::GenerateCredentials(nsIHttpAuthenticableChannel *authChannel,
const char *challenge,
diff -up firefox-48.0/netwerk/protocol/http/nsHttpNTLMAuth.cpp.890908-async-nego firefox-48.0/netwerk/protocol/http/nsHttpNTLMAuth.cpp
--- firefox-48.0/netwerk/protocol/http/nsHttpNTLMAuth.cpp.890908-async-nego 2016-07-25 22:22:06.000000000 +0200
+++ firefox-48.0/netwerk/protocol/http/nsHttpNTLMAuth.cpp 2016-07-27 09:56:55.654261702 +0200
@@ -333,6 +333,21 @@ nsHttpNTLMAuth::ChallengeReceived(nsIHtt
}
NS_IMETHODIMP
+nsHttpNTLMAuth::GenerateCredentialsAsync(nsIHttpAuthenticableChannel *authChannel,
+ nsIHttpAuthenticatorCallback* aCallback,
+ const char *challenge,
+ bool isProxyAuth,
+ const char16_t *domain,
+ const char16_t *username,
+ const char16_t *password,
+ nsISupports *sessionState,
+ nsISupports *continuationState,
+ nsICancelable **aCancellable)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
nsHttpNTLMAuth::GenerateCredentials(nsIHttpAuthenticableChannel *authChannel,
const char *challenge,
bool isProxyAuth,
diff -up firefox-48.0/netwerk/protocol/http/nsIHttpAuthenticator.idl.890908-async-nego firefox-48.0/netwerk/protocol/http/nsIHttpAuthenticator.idl
--- firefox-48.0/netwerk/protocol/http/nsIHttpAuthenticator.idl.890908-async-nego 2016-05-12 19:13:28.000000000 +0200
+++ firefox-48.0/netwerk/protocol/http/nsIHttpAuthenticator.idl 2016-07-27 09:56:55.654261702 +0200
@@ -6,6 +6,8 @@
#include "nsISupports.idl"
interface nsIHttpAuthenticableChannel;
+interface nsIHttpAuthenticatorCallback;
+interface nsICancelable;
/**
* nsIHttpAuthenticator
@@ -18,7 +20,7 @@ interface nsIHttpAuthenticableChannel;
* where <auth-scheme> is the lower-cased value of the authentication scheme
* found in the server challenge per the rules of RFC 2617.
*/
-[scriptable, uuid(16784db0-fcb1-4352-b0c9-6a3a67e3cf79)]
+[scriptable, uuid(fef7db8a-a4e2-49d1-9685-19ed7e309b7d)]
interface nsIHttpAuthenticator : nsISupports
{
/**
@@ -54,6 +56,54 @@ interface nsIHttpAuthenticator : nsISupp
/**
* Called to generate the authentication credentials for a particular
+ * server/proxy challenge asynchronously. Credentials will be sent back
+ * to the server via an Authorization/Proxy-Authorization header.
+ *
+ * @param aChannel
+ * the http channel requesting credentials
+ * @param aCallback
+ * callback function to be called when credentials are available
+ * @param aChallenge
+ * the challenge from the WWW-Authenticate/Proxy-Authenticate
+ * server response header. (possibly from the auth cache.)
+ * @param aProxyAuth
+ * flag indicating whether or not aChallenge is from a proxy.
+ * @param aDomain
+ * string containing the domain name (if appropriate)
+ * @param aUser
+ * string containing the user name
+ * @param aPassword
+ * string containing the password
+ * @param aSessionState
+ * state stored along side the user's identity in the auth cache
+ * for the lifetime of the browser session. if a new auth cache
+ * entry is created for this challenge, then this parameter will
+ * be null. on return, the result will be stored in the new auth
+ * cache entry. this parameter is non-null when an auth cache entry
+ * is being reused. currently modification of session state is not
+ * communicated to caller, thus caching credentials obtained by
+ * asynchronous way is not supported.
+ * @param aContinuationState
+ * state held by the channel between consecutive calls to
+ * generateCredentials, assuming multiple calls are required
+ * to authenticate. this state is held for at most the lifetime of
+ * the channel.
+ * @pram aCancel
+ * returns cancellable runnable object which caller can use to cancel
+ * calling aCallback when finished.
+ */
+ void generateCredentialsAsync(in nsIHttpAuthenticableChannel aChannel,
+ in nsIHttpAuthenticatorCallback aCallback,
+ in string aChallenge,
+ in boolean aProxyAuth,
+ in wstring aDomain,
+ in wstring aUser,
+ in wstring aPassword,
+ in nsISupports aSessionState,
+ in nsISupports aContinuationState,
+ out nsICancelable aCancel);
+ /**
+ * Called to generate the authentication credentials for a particular
* server/proxy challenge. This is the value that will be sent back
* to the server via an Authorization/Proxy-Authorization header.
*