#547: block modal HTTP auth DOS M1312243 M377496 + glue code
This commit is contained in:
parent
9465ea36d8
commit
d60d9721fd
|
@ -3259,6 +3259,10 @@ function BrowserReloadWithFlags(reloadFlags) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset temporary permissions on the current tab. This is done here
|
||||||
|
// because we only want to reset permissions on user reload.
|
||||||
|
delete gBrowser.selectedBrowser.canceledAuthenticationPromptCounter;
|
||||||
|
|
||||||
let windowUtils = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
let windowUtils = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||||
.getInterface(Ci.nsIDOMWindowUtils);
|
.getInterface(Ci.nsIDOMWindowUtils);
|
||||||
|
|
||||||
|
|
|
@ -2679,6 +2679,7 @@ let remote = false;
|
||||||
<parameter name="aTab"/>
|
<parameter name="aTab"/>
|
||||||
<body>
|
<body>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
|
delete this.getBrowserForTab(aTab).canceledAuthenticationPromptCounter;
|
||||||
this.getBrowserForTab(aTab).reload();
|
this.getBrowserForTab(aTab).reload();
|
||||||
]]>
|
]]>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -417,6 +417,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
// occurs in a new tab, we want focus to be restored to the content
|
// occurs in a new tab, we want focus to be restored to the content
|
||||||
// area when the current tab is re-selected.
|
// area when the current tab is re-selected.
|
||||||
gBrowser.selectedBrowser.focus();
|
gBrowser.selectedBrowser.focus();
|
||||||
|
delete gBrowser.selectedBrowser.canceledAuthenticationPromptCounter;
|
||||||
|
|
||||||
let isMouseEvent = aTriggeringEvent instanceof MouseEvent;
|
let isMouseEvent = aTriggeringEvent instanceof MouseEvent;
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,7 @@
|
||||||
#include "nsWhitespaceTokenizer.h"
|
#include "nsWhitespaceTokenizer.h"
|
||||||
#include "nsICookieService.h"
|
#include "nsICookieService.h"
|
||||||
#include "nsIConsoleReportCollector.h"
|
#include "nsIConsoleReportCollector.h"
|
||||||
|
#include "nsILoginManagerPrompter.h"
|
||||||
|
|
||||||
// we want to explore making the document own the load group
|
// we want to explore making the document own the load group
|
||||||
// so we can associate the document URI with the load group.
|
// so we can associate the document URI with the load group.
|
||||||
|
@ -13169,6 +13170,35 @@ nsDocShell::GetAuthPrompt(uint32_t aPromptReason, const nsIID& aIID,
|
||||||
|
|
||||||
// Get the an auth prompter for our window so that the parenting
|
// Get the an auth prompter for our window so that the parenting
|
||||||
// of the dialogs works as it should when using tabs.
|
// of the dialogs works as it should when using tabs.
|
||||||
|
// Since we don't go through E10S, we need to set the browser element
|
||||||
|
// manually (a la dom/ipc/TabParent) so that we can check elements
|
||||||
|
// that may be set on it, such as HTTP Auth DOS (TenFourFox issue 547).
|
||||||
|
|
||||||
|
NS_ASSERTION(mScriptGlobal, "We don't have a script global");
|
||||||
|
if (MOZ_LIKELY(mScriptGlobal)) {
|
||||||
|
nsCOMPtr<Element> frameElement = mScriptGlobal->GetFrameElementInternal();
|
||||||
|
if (MOZ_LIKELY(frameElement)) {
|
||||||
|
nsCOMPtr<nsIContent> frame = do_QueryInterface(frameElement);
|
||||||
|
if (MOZ_LIKELY(frame)) {
|
||||||
|
nsCOMPtr<nsISupports> prompt;
|
||||||
|
nsCOMPtr<nsIDOMWindow> window = do_QueryInterface(frame->OwnerDoc()->GetWindow());
|
||||||
|
if (MOZ_LIKELY(window) &&
|
||||||
|
NS_SUCCEEDED(wwatch->GetPrompt(window, aIID,
|
||||||
|
getter_AddRefs(prompt))) &&
|
||||||
|
MOZ_LIKELY(prompt)) {
|
||||||
|
nsCOMPtr<nsIDOMElement> browser = do_QueryInterface(frameElement);
|
||||||
|
if (MOZ_LIKELY(browser)) {
|
||||||
|
nsCOMPtr<nsILoginManagerPrompter> prompter = do_QueryInterface(prompt);
|
||||||
|
if (MOZ_LIKELY(prompter))
|
||||||
|
prompter->SetE10sData(browser, nullptr);
|
||||||
|
}
|
||||||
|
*aResult = prompt.forget().take();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NS_WARNING("Unable to connect browser to auth prompt, falling back");
|
||||||
|
}
|
||||||
|
|
||||||
return wwatch->GetPrompt(mScriptGlobal, aIID,
|
return wwatch->GetPrompt(mScriptGlobal, aIID,
|
||||||
reinterpret_cast<void**>(aResult));
|
reinterpret_cast<void**>(aResult));
|
||||||
|
|
|
@ -5151,6 +5151,12 @@ pref("toolkit.pageThumbs.screenSizeDivisor", 7);
|
||||||
pref("toolkit.pageThumbs.minWidth", 0);
|
pref("toolkit.pageThumbs.minWidth", 0);
|
||||||
pref("toolkit.pageThumbs.minHeight", 0);
|
pref("toolkit.pageThumbs.minHeight", 0);
|
||||||
|
|
||||||
|
// When a user cancels this number of authentication dialogs coming from
|
||||||
|
// a single web page in a row, all following authentication dialogs will
|
||||||
|
// be blocked (automatically canceled) for that page. The counter resets
|
||||||
|
// when the page is reloaded. To turn this feature off, just set the limit to 0.
|
||||||
|
pref("prompts.authentication_dialog_abuse_limit", 3);
|
||||||
|
|
||||||
pref("tenfourfox.adblock.enabled", false);
|
pref("tenfourfox.adblock.enabled", false);
|
||||||
pref("tenfourfox.adblock.logging.enabled", false);
|
pref("tenfourfox.adblock.logging.enabled", false);
|
||||||
pref("tenfourfox.dom.forms.date", true);
|
pref("tenfourfox.dom.forms.date", true);
|
||||||
|
|
|
@ -117,6 +117,7 @@ struct HttpChannelOpenArgs
|
||||||
OptionalCorsPreflightArgs preflightArgs;
|
OptionalCorsPreflightArgs preflightArgs;
|
||||||
uint32_t initialRwin;
|
uint32_t initialRwin;
|
||||||
bool suspendAfterSynthesizeResponse;
|
bool suspendAfterSynthesizeResponse;
|
||||||
|
uint64_t contentWindowId;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HttpChannelConnectArgs
|
struct HttpChannelConnectArgs
|
||||||
|
|
|
@ -48,8 +48,10 @@
|
||||||
#include "LoadInfo.h"
|
#include "LoadInfo.h"
|
||||||
#include "nsIXULRuntime.h"
|
#include "nsIXULRuntime.h"
|
||||||
#include "nsPIDOMWindow.h"
|
#include "nsPIDOMWindow.h"
|
||||||
|
#include "nsIDOMWindowUtils.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include "HttpBaseChannel.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace net {
|
namespace net {
|
||||||
|
@ -100,6 +102,7 @@ HttpBaseChannel::HttpBaseChannel()
|
||||||
, mTransferSize(0)
|
, mTransferSize(0)
|
||||||
, mDecodedBodySize(0)
|
, mDecodedBodySize(0)
|
||||||
, mEncodedBodySize(0)
|
, mEncodedBodySize(0)
|
||||||
|
, mContentWindowId(0)
|
||||||
, mRequireCORSPreflight(false)
|
, mRequireCORSPreflight(false)
|
||||||
, mReportCollector(new ConsoleReportCollector())
|
, mReportCollector(new ConsoleReportCollector())
|
||||||
, mForceMainDocumentChannel(false)
|
, mForceMainDocumentChannel(false)
|
||||||
|
@ -1100,6 +1103,30 @@ HttpBaseChannel::nsContentEncodings::PrepareForNext(void)
|
||||||
// HttpBaseChannel::nsIHttpChannel
|
// HttpBaseChannel::nsIHttpChannel
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
NS_IMETHODIMP HttpBaseChannel::GetTopLevelContentWindowId(uint64_t *aWindowId)
|
||||||
|
{
|
||||||
|
if (!mContentWindowId) {
|
||||||
|
nsCOMPtr<nsILoadContext> loadContext;
|
||||||
|
GetCallback(loadContext);
|
||||||
|
if (loadContext) {
|
||||||
|
nsCOMPtr<nsIDOMWindow> topWindow;
|
||||||
|
loadContext->GetTopWindow(getter_AddRefs(topWindow));
|
||||||
|
nsCOMPtr<nsIDOMWindowUtils> windowUtils = do_GetInterface(topWindow);
|
||||||
|
if (windowUtils) {
|
||||||
|
windowUtils->GetCurrentInnerWindowID(&mContentWindowId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*aWindowId = mContentWindowId;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP HttpBaseChannel::SetTopLevelContentWindowId(uint64_t aWindowId)
|
||||||
|
{
|
||||||
|
mContentWindowId = aWindowId;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HttpBaseChannel::GetTransferSize(uint64_t *aTransferSize)
|
HttpBaseChannel::GetTransferSize(uint64_t *aTransferSize)
|
||||||
{
|
{
|
||||||
|
|
|
@ -178,6 +178,8 @@ public:
|
||||||
NS_IMETHOD GetIsMainDocumentChannel(bool* aValue) override;
|
NS_IMETHOD GetIsMainDocumentChannel(bool* aValue) override;
|
||||||
NS_IMETHOD SetIsMainDocumentChannel(bool aValue) override;
|
NS_IMETHOD SetIsMainDocumentChannel(bool aValue) override;
|
||||||
NS_IMETHOD GetProtocolVersion(nsACString & aProtocolVersion) override;
|
NS_IMETHOD GetProtocolVersion(nsACString & aProtocolVersion) override;
|
||||||
|
NS_IMETHOD GetTopLevelContentWindowId(uint64_t *aContentWindowId) override;
|
||||||
|
NS_IMETHOD SetTopLevelContentWindowId(uint64_t aContentWindowId) override;
|
||||||
|
|
||||||
// nsIHttpChannelInternal
|
// nsIHttpChannelInternal
|
||||||
NS_IMETHOD GetDocumentURI(nsIURI **aDocumentURI) override;
|
NS_IMETHOD GetDocumentURI(nsIURI **aDocumentURI) override;
|
||||||
|
@ -496,6 +498,10 @@ protected:
|
||||||
nsID mSchedulingContextID;
|
nsID mSchedulingContextID;
|
||||||
bool EnsureSchedulingContextID();
|
bool EnsureSchedulingContextID();
|
||||||
|
|
||||||
|
// ID of the top-level document's inner window this channel is being
|
||||||
|
// originated from.
|
||||||
|
uint64_t mContentWindowId;
|
||||||
|
|
||||||
bool mRequireCORSPreflight;
|
bool mRequireCORSPreflight;
|
||||||
nsTArray<nsCString> mUnsafeHeaders;
|
nsTArray<nsCString> mUnsafeHeaders;
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,8 @@
|
||||||
#include "nsContentSecurityManager.h"
|
#include "nsContentSecurityManager.h"
|
||||||
#include "nsIDeprecationWarner.h"
|
#include "nsIDeprecationWarner.h"
|
||||||
#include "nsICompressConvStats.h"
|
#include "nsICompressConvStats.h"
|
||||||
|
#include "nsIDocument.h"
|
||||||
|
#include "nsIDOMWindowUtils.h"
|
||||||
|
|
||||||
#ifdef OS_POSIX
|
#ifdef OS_POSIX
|
||||||
#include "chrome/common/file_descriptor_set_posix.h"
|
#include "chrome/common/file_descriptor_set_posix.h"
|
||||||
|
@ -1870,6 +1872,18 @@ HttpChannelChild::ContinueAsyncOpen()
|
||||||
return NS_ERROR_ILLEGAL_VALUE;
|
return NS_ERROR_ILLEGAL_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This id identifies the inner window's top-level document,
|
||||||
|
// which changes on every new load or navigation.
|
||||||
|
uint64_t contentWindowId = 0;
|
||||||
|
if (tabChild) {
|
||||||
|
MOZ_ASSERT(tabChild->WebNavigation());
|
||||||
|
nsCOMPtr<nsIDocument> document = tabChild->GetDocument();
|
||||||
|
if (document) {
|
||||||
|
contentWindowId = document->InnerWindowID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SetTopLevelContentWindowId(contentWindowId);
|
||||||
|
|
||||||
HttpChannelOpenArgs openArgs;
|
HttpChannelOpenArgs openArgs;
|
||||||
// No access to HttpChannelOpenArgs members, but they each have a
|
// No access to HttpChannelOpenArgs members, but they each have a
|
||||||
// function with the struct name that returns a ref.
|
// function with the struct name that returns a ref.
|
||||||
|
@ -1970,6 +1984,8 @@ HttpChannelChild::ContinueAsyncOpen()
|
||||||
mSchedulingContextID.ToProvidedString(scid);
|
mSchedulingContextID.ToProvidedString(scid);
|
||||||
openArgs.schedulingContextID().AssignASCII(scid);
|
openArgs.schedulingContextID().AssignASCII(scid);
|
||||||
|
|
||||||
|
openArgs.contentWindowId() = contentWindowId;
|
||||||
|
|
||||||
// The socket transport in the chrome process now holds a logical ref to us
|
// The socket transport in the chrome process now holds a logical ref to us
|
||||||
// until OnStopRequest, or we do a redirect, or we hit an IPDL error.
|
// until OnStopRequest, or we do a redirect, or we hit an IPDL error.
|
||||||
AddIPDLReference();
|
AddIPDLReference();
|
||||||
|
|
|
@ -133,7 +133,8 @@ HttpChannelParent::Init(const HttpChannelCreationArgs& aArgs)
|
||||||
a.loadInfo(), a.synthesizedResponseHead(),
|
a.loadInfo(), a.synthesizedResponseHead(),
|
||||||
a.synthesizedSecurityInfoSerialization(),
|
a.synthesizedSecurityInfoSerialization(),
|
||||||
a.cacheKey(), a.schedulingContextID(), a.preflightArgs(),
|
a.cacheKey(), a.schedulingContextID(), a.preflightArgs(),
|
||||||
a.initialRwin(), a.suspendAfterSynthesizeResponse());
|
a.initialRwin(), a.suspendAfterSynthesizeResponse(),
|
||||||
|
a.contentWindowId());
|
||||||
}
|
}
|
||||||
case HttpChannelCreationArgs::THttpChannelConnectArgs:
|
case HttpChannelCreationArgs::THttpChannelConnectArgs:
|
||||||
{
|
{
|
||||||
|
@ -386,7 +387,8 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
|
||||||
const nsCString& aSchedulingContextID,
|
const nsCString& aSchedulingContextID,
|
||||||
const OptionalCorsPreflightArgs& aCorsPreflightArgs,
|
const OptionalCorsPreflightArgs& aCorsPreflightArgs,
|
||||||
const uint32_t& aInitialRwin,
|
const uint32_t& aInitialRwin,
|
||||||
const bool& aSuspendAfterSynthesizeResponse)
|
const bool& aSuspendAfterSynthesizeResponse,
|
||||||
|
const uint64_t& aContentWindowId)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
|
nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
|
||||||
if (!uri) {
|
if (!uri) {
|
||||||
|
@ -440,6 +442,7 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
|
||||||
return SendFailedAsyncOpen(rv);
|
return SendFailedAsyncOpen(rv);
|
||||||
|
|
||||||
mChannel = static_cast<nsHttpChannel *>(channel.get());
|
mChannel = static_cast<nsHttpChannel *>(channel.get());
|
||||||
|
mChannel->SetTopLevelContentWindowId(aContentWindowId);
|
||||||
mChannel->SetWarningReporter(this);
|
mChannel->SetWarningReporter(this);
|
||||||
mChannel->SetTimingEnabled(true);
|
mChannel->SetTimingEnabled(true);
|
||||||
if (mPBOverride != kPBOverride_Unset) {
|
if (mPBOverride != kPBOverride_Unset) {
|
||||||
|
|
|
@ -129,7 +129,8 @@ protected:
|
||||||
const nsCString& aSchedulingContextID,
|
const nsCString& aSchedulingContextID,
|
||||||
const OptionalCorsPreflightArgs& aCorsPreflightArgs,
|
const OptionalCorsPreflightArgs& aCorsPreflightArgs,
|
||||||
const uint32_t& aInitialRwin,
|
const uint32_t& aInitialRwin,
|
||||||
const bool& aSuspendAfterSynthesizeResponse);
|
const bool& aSuspendAfterSynthesizeResponse,
|
||||||
|
const uint64_t& aContentWindowId);
|
||||||
|
|
||||||
virtual bool RecvSetPriority(const uint16_t& priority) override;
|
virtual bool RecvSetPriority(const uint16_t& priority) override;
|
||||||
virtual bool RecvSetClassOfService(const uint32_t& cos) override;
|
virtual bool RecvSetClassOfService(const uint32_t& cos) override;
|
||||||
|
|
|
@ -56,6 +56,18 @@ NullHttpChannel::Init(nsIURI *aURI,
|
||||||
// NullHttpChannel::nsIHttpChannel
|
// NullHttpChannel::nsIHttpChannel
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
NullHttpChannel::GetTopLevelContentWindowId(uint64_t *aWindowId)
|
||||||
|
{
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
NullHttpChannel::SetTopLevelContentWindowId(uint64_t aWindowId)
|
||||||
|
{
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
NullHttpChannel::GetTransferSize(uint64_t *aTransferSize)
|
NullHttpChannel::GetTransferSize(uint64_t *aTransferSize)
|
||||||
{
|
{
|
||||||
|
|
|
@ -384,4 +384,10 @@ interface nsIHttpChannel : nsIChannel
|
||||||
* Identifies the scheduling context for this load.
|
* Identifies the scheduling context for this load.
|
||||||
*/
|
*/
|
||||||
[noscript] attribute nsID schedulingContextID;
|
[noscript] attribute nsID schedulingContextID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ID of the top-level document's inner window. Identifies the content
|
||||||
|
* this channel is being loaded in.
|
||||||
|
*/
|
||||||
|
attribute uint64_t topLevelContentWindowId;
|
||||||
};
|
};
|
||||||
|
|
|
@ -721,6 +721,21 @@ nsViewSourceChannel::OnDataAvailable(nsIRequest *aRequest, nsISupports* aContext
|
||||||
// We want to forward most of nsIHttpChannel over to mHttpChannel, but we want
|
// We want to forward most of nsIHttpChannel over to mHttpChannel, but we want
|
||||||
// to override GetRequestHeader and VisitHeaders. The reason is that we don't
|
// to override GetRequestHeader and VisitHeaders. The reason is that we don't
|
||||||
// want various headers like Link: and Refresh: applying to view-source.
|
// want various headers like Link: and Refresh: applying to view-source.
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsViewSourceChannel::GetTopLevelContentWindowId(uint64_t *aWindowId)
|
||||||
|
{
|
||||||
|
return !mHttpChannel ? NS_ERROR_NULL_POINTER :
|
||||||
|
mHttpChannel->GetTopLevelContentWindowId(aWindowId);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsViewSourceChannel::SetTopLevelContentWindowId(uint64_t aWindowId)
|
||||||
|
{
|
||||||
|
return !mHttpChannel ? NS_ERROR_NULL_POINTER :
|
||||||
|
mHttpChannel->SetTopLevelContentWindowId(aWindowId);
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsViewSourceChannel::GetRequestMethod(nsACString & aRequestMethod)
|
nsViewSourceChannel::GetRequestMethod(nsACString & aRequestMethod)
|
||||||
{
|
{
|
||||||
|
|
|
@ -95,30 +95,64 @@ LoginManagerPromptFactory.prototype = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._asyncPromptInProgress = true;
|
// Set up a counter for ensuring that the basic auth prompt can not
|
||||||
prompt.inProgress = true;
|
// be abused for DOS-style attacks. With this counter, each eTLD+1
|
||||||
|
// per browser will get a limited number of times a user can
|
||||||
|
// cancel the prompt until we stop showing it.
|
||||||
|
let browser = prompter._browser;
|
||||||
|
let baseDomain = null;
|
||||||
|
if (browser) {
|
||||||
|
try {
|
||||||
|
baseDomain = Services.eTLD.getBaseDomainFromHost(hostname);
|
||||||
|
} catch (e) {
|
||||||
|
baseDomain = hostname;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!browser.canceledAuthenticationPromptCounter) {
|
||||||
|
browser.canceledAuthenticationPromptCounter = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!browser.canceledAuthenticationPromptCounter[baseDomain]) {
|
||||||
|
browser.canceledAuthenticationPromptCounter[baseDomain] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var runnable = {
|
var runnable = {
|
||||||
|
cancel: false,
|
||||||
run : function() {
|
run : function() {
|
||||||
var ok = false;
|
var ok = false;
|
||||||
try {
|
if (!this.cancel) {
|
||||||
self.log("_doAsyncPrompt:run - performing the prompt for '" + hashKey + "'");
|
try {
|
||||||
ok = prompter.promptAuth(prompt.channel,
|
self.log("_doAsyncPrompt:run - performing the prompt for '" + hashKey + "'");
|
||||||
prompt.level,
|
ok = prompter.promptAuth(prompt.channel,
|
||||||
prompt.authInfo);
|
prompt.level,
|
||||||
} catch (e if (e instanceof Components.Exception) &&
|
prompt.authInfo);
|
||||||
e.result == Cr.NS_ERROR_NOT_AVAILABLE) {
|
} catch (e) {
|
||||||
self.log("_doAsyncPrompt:run bypassed, UI is not available in this context");
|
if (e instanceof Components.Exception &&
|
||||||
} catch (e) {
|
e.result == Cr.NS_ERROR_NOT_AVAILABLE) {
|
||||||
Components.utils.reportError("LoginManagerPrompter: " +
|
self.log("_doAsyncPrompt:run bypassed, UI is not available in this context");
|
||||||
"_doAsyncPrompt:run: " + e + "\n");
|
} else {
|
||||||
}
|
Components.utils.reportError("LoginManagerPrompter: " +
|
||||||
|
"_doAsyncPrompt:run: " + e + "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delete self._asyncPrompts[hashKey];
|
delete self._asyncPrompts[hashKey];
|
||||||
prompt.inProgress = false;
|
prompt.inProgress = false;
|
||||||
self._asyncPromptInProgress = false;
|
self._asyncPromptInProgress = false;
|
||||||
|
|
||||||
|
if (browser) {
|
||||||
|
// Reset the counter state if the user replied to a prompt and actually
|
||||||
|
// tried to login (vs. simply clicking any button to get out).
|
||||||
|
if (ok && (prompt.authInfo.username || prompt.authInfo.password)) {
|
||||||
|
browser.canceledAuthenticationPromptCounter[baseDomain] = 0;
|
||||||
|
} else {
|
||||||
|
browser.canceledAuthenticationPromptCounter[baseDomain] += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (var consumer of prompt.consumers) {
|
for (var consumer of prompt.consumers) {
|
||||||
if (!consumer.callback)
|
if (!consumer.callback)
|
||||||
|
@ -128,16 +162,37 @@ LoginManagerPromptFactory.prototype = {
|
||||||
|
|
||||||
self.log("Calling back to " + consumer.callback + " ok=" + ok);
|
self.log("Calling back to " + consumer.callback + " ok=" + ok);
|
||||||
try {
|
try {
|
||||||
if (ok)
|
if (ok) {
|
||||||
consumer.callback.onAuthAvailable(consumer.context, prompt.authInfo);
|
consumer.callback.onAuthAvailable(consumer.context, prompt.authInfo);
|
||||||
else
|
} else {
|
||||||
consumer.callback.onAuthCancelled(consumer.context, true);
|
consumer.callback.onAuthCancelled(consumer.context, !this.cancel);
|
||||||
|
}
|
||||||
} catch (e) { /* Throw away exceptions caused by callback */ }
|
} catch (e) { /* Throw away exceptions caused by callback */ }
|
||||||
}
|
}
|
||||||
self._doAsyncPrompt();
|
self._doAsyncPrompt();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var cancelDialogLimit = Services.prefs.getIntPref("prompts.authentication_dialog_abuse_limit");
|
||||||
|
|
||||||
|
if (browser) {
|
||||||
|
let cancelationCounter = browser.canceledAuthenticationPromptCounter[baseDomain];
|
||||||
|
this.log("cancelationCounter ="+ cancelationCounter);
|
||||||
|
if (cancelDialogLimit && cancelationCounter >= cancelDialogLimit) {
|
||||||
|
this.log("Blocking auth dialog, due to exceeding dialog bloat limit");
|
||||||
|
delete this._asyncPrompts[hashKey];
|
||||||
|
|
||||||
|
// just make the runnable cancel all consumers
|
||||||
|
runnable.cancel = true;
|
||||||
|
} else {
|
||||||
|
this._asyncPromptInProgress = true;
|
||||||
|
prompt.inProgress = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this._asyncPromptInProgress = true;
|
||||||
|
prompt.inProgress = true;
|
||||||
|
}
|
||||||
|
|
||||||
Services.tm.mainThread.dispatch(runnable, Ci.nsIThread.DISPATCH_NORMAL);
|
Services.tm.mainThread.dispatch(runnable, Ci.nsIThread.DISPATCH_NORMAL);
|
||||||
this.log("_doAsyncPrompt:run dispatched");
|
this.log("_doAsyncPrompt:run dispatched");
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue