mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 07:13:20 +00:00
Bug 1631405 - Move nsISecureBrowserUI to be owned by the canonical browsing context instead of docshell. r=nika,ckerschb,Gijs,webcompat-reviewers,twisniewski
This removes all docshell nsISecureBrowserUI and mixed content properties, and moves them into CanonicalBrowsingContext/WindowGlobalParent. It makes the mixed content blocker just compute the state for the current load, and then send the results to the parent process, where we update the security state accordingly. I think we could in the future remove onSecurityChange entirely, and instead just fire an event to the <browser> element notifying it of changes to the queryable securityUI. Unfortunately we have a lot of existing code that depends on specific ordering between onSecurityChange and onLocationChange, so I had to hook into the RemoteWebProgress implementation in BrowserParent to mimic the same timings. Differential Revision: https://phabricator.services.mozilla.com/D75447
This commit is contained in:
parent
5b64e9bae2
commit
240d417eb6
@ -148,8 +148,6 @@ class ReportSiteIssueHelperChild extends JSWindowActorChild {
|
||||
case "GetBlockingStatus":
|
||||
const { docShell } = this;
|
||||
return {
|
||||
hasMixedActiveContentBlocked: docShell.hasMixedActiveContentBlocked,
|
||||
hasMixedDisplayContentBlocked: docShell.hasMixedDisplayContentBlocked,
|
||||
hasTrackingContentBlocked: docShell.hasTrackingContentBlocked,
|
||||
};
|
||||
}
|
||||
|
@ -31,6 +31,14 @@ this.tabExtras = class extends ExtensionAPI {
|
||||
const promises = actors.map(actor => actor.sendQuery("GetLog"));
|
||||
const logs = await Promise.all(promises);
|
||||
const info = await actors[0].sendQuery("GetBlockingStatus");
|
||||
info.hasMixedActiveContentBlocked = !!(
|
||||
browsingContext.secureBrowserUI.state &
|
||||
Ci.nsIWebProgressListener.STATE_BLOCKED_MIXED_ACTIVE_CONTENT
|
||||
);
|
||||
info.hasMixedDisplayContentBlocked = !!(
|
||||
browsingContext.secureBrowserUI.state &
|
||||
Ci.nsIWebProgressListener.STATE_BLOCKED_MIXED_DISPLAY_CONTENT
|
||||
);
|
||||
info.log = logs
|
||||
.flat()
|
||||
.sort((a, b) => a.timeStamp - b.timeStamp)
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "ipc/IPCMessageUtils.h"
|
||||
|
||||
#include "mozilla/dom/CanonicalBrowsingContext.h"
|
||||
#include "mozilla/dom/BrowserParent.h"
|
||||
#include "mozilla/dom/BrowsingContextGroup.h"
|
||||
#include "mozilla/dom/BrowsingContextBinding.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "nsIWebBrowserChrome.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsSHistory.h"
|
||||
#include "nsSecureBrowserUI.h"
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
@ -114,6 +115,23 @@ void CanonicalBrowsingContext::SetOwnerProcessId(uint64_t aProcessId) {
|
||||
mProcessId = aProcessId;
|
||||
}
|
||||
|
||||
nsISecureBrowserUI* CanonicalBrowsingContext::GetSecureBrowserUI() {
|
||||
if (!IsTop()) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!mSecureBrowserUI) {
|
||||
mSecureBrowserUI = new nsSecureBrowserUI(this);
|
||||
}
|
||||
return mSecureBrowserUI;
|
||||
}
|
||||
|
||||
void CanonicalBrowsingContext::
|
||||
UpdateSecurityStateForLocationOrMixedContentChange() {
|
||||
if (mSecureBrowserUI) {
|
||||
mSecureBrowserUI->UpdateForLocationOrMixedContentChange();
|
||||
}
|
||||
}
|
||||
|
||||
void CanonicalBrowsingContext::SetInFlightProcessId(uint64_t aProcessId) {
|
||||
// We can't handle more than one in-flight process change at a time.
|
||||
MOZ_ASSERT_IF(aProcessId, mInFlightProcessId == 0);
|
||||
|
@ -18,7 +18,9 @@
|
||||
#include "nsHashKeys.h"
|
||||
|
||||
class nsISHistory;
|
||||
#include "nsISecureBrowserUI.h"
|
||||
|
||||
class nsSecureBrowserUI;
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
class DocumentLoadListener;
|
||||
@ -141,6 +143,15 @@ class CanonicalBrowsingContext final : public BrowsingContext {
|
||||
bool AttemptLoadURIInParent(nsDocShellLoadState* aLoadState,
|
||||
uint32_t* aLoadIdentifier);
|
||||
|
||||
// Get or create a secure browser UI for this BrowsingContext
|
||||
nsISecureBrowserUI* GetSecureBrowserUI();
|
||||
|
||||
// Called when the current URI changes (from an
|
||||
// nsIWebProgressListener::OnLocationChange event, so that we
|
||||
// can update our security UI for the new location, or when the
|
||||
// mixed content state for our current window is changed.
|
||||
void UpdateSecurityStateForLocationOrMixedContentChange();
|
||||
|
||||
protected:
|
||||
// Called when the browsing context is being discarded.
|
||||
void CanonicalDiscard();
|
||||
@ -216,6 +227,8 @@ class CanonicalBrowsingContext final : public BrowsingContext {
|
||||
|
||||
nsTArray<SessionHistoryEntryAndId> mLoadingEntries;
|
||||
RefPtr<SessionHistoryEntry> mActiveEntry;
|
||||
|
||||
RefPtr<nsSecureBrowserUI> mSecureBrowserUI;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -218,6 +218,24 @@ void WindowContext::Discard() {
|
||||
Group()->Unregister(this);
|
||||
}
|
||||
|
||||
void WindowContext::AddMixedContentSecurityState(uint32_t aStateFlags) {
|
||||
MOZ_ASSERT(TopWindowContext() == this);
|
||||
MOZ_ASSERT((aStateFlags &
|
||||
(nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT |
|
||||
nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT |
|
||||
nsIWebProgressListener::STATE_BLOCKED_MIXED_DISPLAY_CONTENT |
|
||||
nsIWebProgressListener::STATE_BLOCKED_MIXED_ACTIVE_CONTENT)) ==
|
||||
aStateFlags,
|
||||
"Invalid flags specified!");
|
||||
|
||||
if (XRE_IsParentProcess()) {
|
||||
Canonical()->AddMixedContentSecurityState(aStateFlags);
|
||||
} else {
|
||||
ContentChild* child = ContentChild::GetSingleton();
|
||||
child->SendAddMixedContentSecurityState(this, aStateFlags);
|
||||
}
|
||||
}
|
||||
|
||||
WindowContext::IPCInitializer WindowContext::GetIPCInitializer() {
|
||||
IPCInitializer init;
|
||||
init.mInnerWindowId = mInnerWindowId;
|
||||
|
@ -92,6 +92,12 @@ class WindowContext : public nsISupports, public nsWrapperCache {
|
||||
|
||||
static void CreateFromIPC(IPCInitializer&& aInit);
|
||||
|
||||
// Add new mixed content security state flags.
|
||||
// These should be some of the four nsIWebProgressListener
|
||||
// 'MIXED' state flags, and should only be called on the
|
||||
// top window context.
|
||||
void AddMixedContentSecurityState(uint32_t aStateFlags);
|
||||
|
||||
protected:
|
||||
WindowContext(BrowsingContext* aBrowsingContext, uint64_t aInnerWindowId,
|
||||
uint64_t aOuterWindowId, bool aInProcess, FieldTuple&& aFields);
|
||||
|
@ -501,7 +501,8 @@ already_AddRefed<nsDocShell> nsDocShell::Create(
|
||||
// various methods via which nsDocLoader can be notified. Note that this
|
||||
// holds an nsWeakPtr to |ds|, so it's ok.
|
||||
rv = ds->AddProgressListener(ds, nsIWebProgress::NOTIFY_STATE_DOCUMENT |
|
||||
nsIWebProgress::NOTIFY_STATE_NETWORK);
|
||||
nsIWebProgress::NOTIFY_STATE_NETWORK |
|
||||
nsIWebProgress::NOTIFY_LOCATION);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -1400,40 +1401,6 @@ void nsDocShell::GetParentCharset(const Encoding*& aCharset,
|
||||
NS_IF_ADDREF(*aPrincipal = mParentCharsetPrincipal);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetHasMixedActiveContentLoaded(bool* aHasMixedActiveContentLoaded) {
|
||||
RefPtr<Document> doc(GetDocument());
|
||||
*aHasMixedActiveContentLoaded = doc && doc->GetHasMixedActiveContentLoaded();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetHasMixedActiveContentBlocked(
|
||||
bool* aHasMixedActiveContentBlocked) {
|
||||
RefPtr<Document> doc(GetDocument());
|
||||
*aHasMixedActiveContentBlocked =
|
||||
doc && doc->GetHasMixedActiveContentBlocked();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetHasMixedDisplayContentLoaded(
|
||||
bool* aHasMixedDisplayContentLoaded) {
|
||||
RefPtr<Document> doc(GetDocument());
|
||||
*aHasMixedDisplayContentLoaded =
|
||||
doc && doc->GetHasMixedDisplayContentLoaded();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetHasMixedDisplayContentBlocked(
|
||||
bool* aHasMixedDisplayContentBlocked) {
|
||||
RefPtr<Document> doc(GetDocument());
|
||||
*aHasMixedDisplayContentBlocked =
|
||||
doc && doc->GetHasMixedDisplayContentBlocked();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetHasTrackingContentBlocked(Promise** aPromise) {
|
||||
MOZ_ASSERT(aPromise);
|
||||
@ -1974,20 +1941,6 @@ nsDocShell::TabToTreeOwner(bool aForward, bool aForDocumentNavigation,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetSecurityUI(nsISecureBrowserUI** aSecurityUI) {
|
||||
NS_IF_ADDREF(*aSecurityUI = mSecurityUI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetSecurityUI(nsISecureBrowserUI* aSecurityUI) {
|
||||
MOZ_ASSERT(!mIsBeingDestroyed);
|
||||
|
||||
mSecurityUI = aSecurityUI;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetLoadURIDelegate(nsILoadURIDelegate** aLoadURIDelegate) {
|
||||
nsCOMPtr<nsILoadURIDelegate> delegate = GetLoadURIDelegate();
|
||||
@ -4348,9 +4301,6 @@ nsDocShell::Destroy() {
|
||||
|
||||
mChromeEventHandler = nullptr;
|
||||
|
||||
// required to break ref cycle
|
||||
mSecurityUI = nullptr;
|
||||
|
||||
// Cancel any timers that were set for this docshell; this is needed
|
||||
// to break the cycle between us and the timers.
|
||||
CancelRefreshURITimers();
|
||||
@ -5623,7 +5573,17 @@ nsDocShell::OnStateChange(nsIWebProgress* aProgress, nsIRequest* aRequest,
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::OnLocationChange(nsIWebProgress* aProgress, nsIRequest* aRequest,
|
||||
nsIURI* aURI, uint32_t aFlags) {
|
||||
MOZ_ASSERT_UNREACHABLE("notification excluded in AddProgressListener(...)");
|
||||
if (XRE_IsParentProcess()) {
|
||||
// Since we've now changed Documents, notify the BrowsingContext that we've
|
||||
// changed. Ideally we'd just let the BrowsingContext do this when it
|
||||
// changes the current window global, but that happens before this and we
|
||||
// have a lot of tests that depend on the specific ordering of messages.
|
||||
if (!(aFlags & nsIWebProgressListener::LOCATION_CHANGE_SAME_DOCUMENT)) {
|
||||
GetBrowsingContext()
|
||||
->Canonical()
|
||||
->UpdateSecurityStateForLocationOrMixedContentChange();
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1146,9 +1146,6 @@ class nsDocShell final : public nsDocLoader,
|
||||
// Editor data, if this document is designMode or contentEditable.
|
||||
mozilla::UniquePtr<nsDocShellEditorData> mEditorData;
|
||||
|
||||
// Secure browser UI object
|
||||
nsCOMPtr<nsISecureBrowserUI> mSecurityUI;
|
||||
|
||||
// The URI we're currently loading. This is only relevant during the
|
||||
// firing of a pagehide/unload. The caller of FirePageHideNotification()
|
||||
// is responsible for setting it and unsetting it. It may be null if the
|
||||
|
@ -353,12 +353,6 @@ interface nsIDocShell : nsIDocShellTreeItem
|
||||
|
||||
attribute nsILayoutHistoryState layoutHistoryState;
|
||||
|
||||
/**
|
||||
* The SecureBrowserUI object for this docshell. This is set by XUL
|
||||
* <browser> or nsWebBrowser for their root docshell.
|
||||
*/
|
||||
attribute nsISecureBrowserUI securityUI;
|
||||
|
||||
/**
|
||||
* Object used to delegate URI loading to an upper context.
|
||||
* Currently only set for GeckoView to allow handling of load requests
|
||||
@ -466,45 +460,6 @@ interface nsIDocShell : nsIDocShellTreeItem
|
||||
*/
|
||||
readonly attribute boolean isInUnload;
|
||||
|
||||
/**
|
||||
* This attribute determines whether Mixed Active Content is loaded on the
|
||||
* document. When it is true, mixed active content was not blocked and has
|
||||
* loaded (or is about to load) on the page. When it is false, mixed active content
|
||||
* has not loaded on the page, either because there was no mixed active content
|
||||
* requests on the page or such requests were blocked by nsMixedContentBlocker.
|
||||
* This boolean is set to true in nsMixedContentBlocker if Mixed Active Content
|
||||
* is allowed (either explicitly on the page by the user or when the about:config
|
||||
* setting security.mixed_content.block_active_content is set to false).
|
||||
*/
|
||||
[infallible] readonly attribute boolean hasMixedActiveContentLoaded;
|
||||
|
||||
/**
|
||||
* This attribute determines whether a document has Mixed Active Content
|
||||
* that has been blocked from loading. When it is true, there is definitely
|
||||
* mixed active content on a page that has been blocked by
|
||||
* nsMixedContentBlocker. When it is false, there may or may not be mixed
|
||||
* active content on a page, but if there is, it will load. Note that if the
|
||||
* about:config setting security.mixed_content.block_active_content is set
|
||||
* false, this boolean will be false, since blocking active content has been
|
||||
* disabled.
|
||||
*/
|
||||
[infallible] readonly attribute boolean hasMixedActiveContentBlocked;
|
||||
|
||||
/**
|
||||
* This attribute determines whether Mixed Display Content is loaded on the
|
||||
* document. When it is true, mixed display content was not blocked and has
|
||||
* loaded (or is about to load) on the page. Similar behavior to
|
||||
* hasMixedActiveContentLoaded.
|
||||
*/
|
||||
[infallible] readonly attribute boolean hasMixedDisplayContentLoaded;
|
||||
|
||||
/**
|
||||
* This attribute determines whether a document has Mixed Display Content
|
||||
* that has been blocked from loading. Similar behavior to
|
||||
* hasMixedActiveContentBlocked.
|
||||
*/
|
||||
[infallible] readonly attribute boolean hasMixedDisplayContentBlocked;
|
||||
|
||||
/**
|
||||
* Disconnects this docshell's editor from its window, and stores the
|
||||
* editor data in the open document's session history entry. This
|
||||
|
@ -1846,40 +1846,6 @@ Document::~Document() {
|
||||
|
||||
// don't report for about: pages
|
||||
if (!IsAboutPage()) {
|
||||
// Record the page load
|
||||
uint32_t pageLoaded = 1;
|
||||
Accumulate(Telemetry::MIXED_CONTENT_UNBLOCK_COUNTER, pageLoaded);
|
||||
// Record the mixed content status of the docshell in Telemetry
|
||||
enum {
|
||||
NO_MIXED_CONTENT = 0, // There is no Mixed Content on the page
|
||||
MIXED_DISPLAY_CONTENT =
|
||||
1, // The page attempted to load Mixed Display Content
|
||||
MIXED_ACTIVE_CONTENT =
|
||||
2, // The page attempted to load Mixed Active Content
|
||||
MIXED_DISPLAY_AND_ACTIVE_CONTENT =
|
||||
3 // The page attempted to load Mixed Display & Mixed Active
|
||||
// Content
|
||||
};
|
||||
|
||||
bool mixedActiveLoaded = GetHasMixedActiveContentLoaded();
|
||||
bool mixedActiveBlocked = GetHasMixedActiveContentBlocked();
|
||||
|
||||
bool mixedDisplayLoaded = GetHasMixedDisplayContentLoaded();
|
||||
bool mixedDisplayBlocked = GetHasMixedDisplayContentBlocked();
|
||||
|
||||
bool hasMixedDisplay = (mixedDisplayBlocked || mixedDisplayLoaded);
|
||||
bool hasMixedActive = (mixedActiveBlocked || mixedActiveLoaded);
|
||||
|
||||
uint32_t mixedContentLevel = NO_MIXED_CONTENT;
|
||||
if (hasMixedDisplay && hasMixedActive) {
|
||||
mixedContentLevel = MIXED_DISPLAY_AND_ACTIVE_CONTENT;
|
||||
} else if (hasMixedActive) {
|
||||
mixedContentLevel = MIXED_ACTIVE_CONTENT;
|
||||
} else if (hasMixedDisplay) {
|
||||
mixedContentLevel = MIXED_DISPLAY_CONTENT;
|
||||
}
|
||||
Accumulate(Telemetry::MIXED_CONTENT_PAGE_LOAD, mixedContentLevel);
|
||||
|
||||
// record CSP telemetry on this document
|
||||
if (mHasCSP) {
|
||||
Accumulate(Telemetry::CSP_DOCUMENTS_COUNT, 1);
|
||||
|
@ -1050,96 +1050,6 @@ class Document : public nsINode,
|
||||
*/
|
||||
void SetBidiOptions(uint32_t aBidiOptions) { mBidiOptions = aBidiOptions; }
|
||||
|
||||
/**
|
||||
* Get the has mixed active content loaded flag for this document.
|
||||
*/
|
||||
bool GetHasMixedActiveContentLoaded() {
|
||||
return mMixedContentFlags &
|
||||
nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the has mixed active content loaded flag for this document.
|
||||
*/
|
||||
void SetHasMixedActiveContentLoaded(bool aHasMixedActiveContentLoaded) {
|
||||
if (aHasMixedActiveContentLoaded) {
|
||||
mMixedContentFlags |=
|
||||
nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT;
|
||||
} else {
|
||||
mMixedContentFlags &=
|
||||
~nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mixed active content blocked flag for this document.
|
||||
*/
|
||||
bool GetHasMixedActiveContentBlocked() {
|
||||
return mMixedContentFlags &
|
||||
nsIWebProgressListener::STATE_BLOCKED_MIXED_ACTIVE_CONTENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the mixed active content blocked flag for this document.
|
||||
*/
|
||||
void SetHasMixedActiveContentBlocked(bool aHasMixedActiveContentBlocked) {
|
||||
if (aHasMixedActiveContentBlocked) {
|
||||
mMixedContentFlags |=
|
||||
nsIWebProgressListener::STATE_BLOCKED_MIXED_ACTIVE_CONTENT;
|
||||
} else {
|
||||
mMixedContentFlags &=
|
||||
~nsIWebProgressListener::STATE_BLOCKED_MIXED_ACTIVE_CONTENT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the has mixed display content loaded flag for this document.
|
||||
*/
|
||||
bool GetHasMixedDisplayContentLoaded() {
|
||||
return mMixedContentFlags &
|
||||
nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the has mixed display content loaded flag for this document.
|
||||
*/
|
||||
void SetHasMixedDisplayContentLoaded(bool aHasMixedDisplayContentLoaded) {
|
||||
if (aHasMixedDisplayContentLoaded) {
|
||||
mMixedContentFlags |=
|
||||
nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT;
|
||||
} else {
|
||||
mMixedContentFlags &=
|
||||
~nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mixed display content blocked flag for this document.
|
||||
*/
|
||||
bool GetHasMixedDisplayContentBlocked() {
|
||||
return mMixedContentFlags &
|
||||
nsIWebProgressListener::STATE_BLOCKED_MIXED_DISPLAY_CONTENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the mixed display content blocked flag for this document.
|
||||
*/
|
||||
void SetHasMixedDisplayContentBlocked(bool aHasMixedDisplayContentBlocked) {
|
||||
if (aHasMixedDisplayContentBlocked) {
|
||||
mMixedContentFlags |=
|
||||
nsIWebProgressListener::STATE_BLOCKED_MIXED_DISPLAY_CONTENT;
|
||||
} else {
|
||||
mMixedContentFlags &=
|
||||
~nsIWebProgressListener::STATE_BLOCKED_MIXED_DISPLAY_CONTENT;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t GetMixedContentFlags() const { return mMixedContentFlags; }
|
||||
|
||||
void AddMixedContentFlags(uint32_t aMixedContentFlags) {
|
||||
mMixedContentFlags |= aMixedContentFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set CSP flag for this document.
|
||||
*/
|
||||
@ -4390,8 +4300,6 @@ class Document : public nsINode,
|
||||
// GetPermissionDelegateHandler
|
||||
RefPtr<PermissionDelegateHandler> mPermissionDelegateHandler;
|
||||
|
||||
uint32_t mMixedContentFlags = 0;
|
||||
|
||||
// True if BIDI is enabled.
|
||||
bool mBidiEnabled : 1;
|
||||
// True if we may need to recompute the language prefs for this document.
|
||||
|
@ -1878,6 +1878,7 @@ addExternalIface('nsIDocShell', nativeType='nsIDocShell', notflattened=True)
|
||||
addExternalIface('nsIContentChild', nativeType='nsIContentChild', notflattened=True)
|
||||
addExternalIface('nsIContentParent', nativeType='nsIContentParent', notflattened=True)
|
||||
addExternalIface('nsIReferrerInfo', nativeType='nsIReferrerInfo', notflattened=True)
|
||||
addExternalIface('nsISecureBrowserUI', nativeType='nsISecureBrowserUI', notflattened=True)
|
||||
addExternalIface('nsIWebNavigation', nativeType='nsIWebNavigation', notflattened=True)
|
||||
addExternalIface('nsIEditor', nativeType='nsIEditor', notflattened=True)
|
||||
addExternalIface('nsIVariant', nativeType='nsIVariant', notflattened=True)
|
||||
|
@ -4,6 +4,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
interface nsIDocShell;
|
||||
interface nsISecureBrowserUI;
|
||||
|
||||
interface mixin LoadContextMixin {
|
||||
readonly attribute WindowProxy? associatedWindow;
|
||||
@ -125,6 +126,8 @@ interface CanonicalBrowsingContext : BrowsingContext {
|
||||
void notifyStartDelayedAutoplayMedia();
|
||||
void notifyMediaMutedChanged(boolean muted);
|
||||
|
||||
readonly attribute nsISecureBrowserUI? secureBrowserUI;
|
||||
|
||||
static unsigned long countSiteOrigins(sequence<BrowsingContext> roots);
|
||||
|
||||
/**
|
||||
|
@ -160,20 +160,6 @@ interface nsIBrowser : nsISupports
|
||||
in uint64_t aRequestContextID,
|
||||
in AString aContentType);
|
||||
|
||||
/**
|
||||
* Called by Gecko when a security chang event needs to update the event
|
||||
* state stored in the security UI object stored in the parent process.
|
||||
*
|
||||
* @param aSecurityInfo the transport security information from the content
|
||||
* process
|
||||
* @param aState the flags from the OnSecurityChange event that triggered
|
||||
* this method, as outlined in nsIWebProgressListener
|
||||
* @param aIsSecureContext whether or not the context is secure
|
||||
*/
|
||||
void updateSecurityUIForSecurityChange(in nsITransportSecurityInfo aSecurityInfo,
|
||||
in uint32_t aState,
|
||||
in boolean aIsSecureContext);
|
||||
|
||||
/**
|
||||
* Called by Gecko when it wants to change the process which is currently
|
||||
* being used to render content in this tab.
|
||||
|
@ -3711,56 +3711,9 @@ NS_IMETHODIMP BrowserChild::OnStatusChange(nsIWebProgress* aWebProgress,
|
||||
NS_IMETHODIMP BrowserChild::OnSecurityChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest,
|
||||
uint32_t aState) {
|
||||
if (!IPCOpen() || !mShouldSendWebProgressEventsToParent) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Maybe<WebProgressData> webProgressData;
|
||||
RequestData requestData;
|
||||
|
||||
MOZ_TRY(PrepareProgressListenerData(aWebProgress, aRequest, webProgressData,
|
||||
requestData));
|
||||
|
||||
Maybe<WebProgressSecurityChangeData> securityChangeData;
|
||||
|
||||
if (aWebProgress && webProgressData->isTopLevel()) {
|
||||
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
|
||||
if (!docShell) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsITransportSecurityInfo> securityInfo;
|
||||
{
|
||||
nsCOMPtr<nsISecureBrowserUI> securityUI;
|
||||
MOZ_TRY(docShell->GetSecurityUI(getter_AddRefs(securityUI)));
|
||||
|
||||
if (securityUI) {
|
||||
MOZ_TRY(securityUI->GetSecInfo(getter_AddRefs(securityInfo)));
|
||||
}
|
||||
}
|
||||
|
||||
bool isSecureContext = false;
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindowOuter> outerWindow = do_GetInterface(docShell);
|
||||
if (!outerWindow) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (nsPIDOMWindowInner* window = outerWindow->GetCurrentInnerWindow()) {
|
||||
isSecureContext = window->IsSecureContext();
|
||||
} else {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
securityChangeData.emplace();
|
||||
securityChangeData->securityInfo() = ToRefPtr(std::move(securityInfo));
|
||||
securityChangeData->isSecureContext() = isSecureContext;
|
||||
}
|
||||
|
||||
Unused << SendOnSecurityChange(webProgressData, requestData, aState,
|
||||
securityChangeData);
|
||||
|
||||
// Security changes are now handled entirely in the parent process
|
||||
// so we don't need to worry about forwarding them (and we shouldn't
|
||||
// be receiving any to forward).
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -116,6 +116,7 @@
|
||||
#include "MMPrinter.h"
|
||||
#include "SessionStoreFunctions.h"
|
||||
#include "mozilla/dom/CrashReport.h"
|
||||
#include "nsISecureBrowserUI.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
# include "mozilla/plugins/PluginWidgetParent.h"
|
||||
@ -2703,6 +2704,13 @@ mozilla::ipc::IPCResult BrowserParent::RecvOnLocationChange(
|
||||
Unused << managerAsListener->OnLocationChange(webProgress, request, aLocation,
|
||||
aFlags);
|
||||
|
||||
// Since we've now changed Documents, notify the BrowsingContext that we've
|
||||
// changed. Ideally we'd just let the BrowsingContext do this when it changes
|
||||
// the current window global, but that happens before this and we have a lot
|
||||
// of tests that depend on the specific ordering of messages.
|
||||
if (!(aFlags & nsIWebProgressListener::LOCATION_CHANGE_SAME_DOCUMENT)) {
|
||||
GetBrowsingContext()->UpdateSecurityStateForLocationOrMixedContentChange();
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
@ -2734,36 +2742,6 @@ mozilla::ipc::IPCResult BrowserParent::RecvOnStatusChange(
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult BrowserParent::RecvOnSecurityChange(
|
||||
const Maybe<WebProgressData>& aWebProgressData,
|
||||
const RequestData& aRequestData, const uint32_t aState,
|
||||
const Maybe<WebProgressSecurityChangeData>& aSecurityChangeData) {
|
||||
nsCOMPtr<nsIBrowser> browser;
|
||||
nsCOMPtr<nsIWebProgress> manager;
|
||||
nsCOMPtr<nsIWebProgressListener> managerAsListener;
|
||||
if (!GetWebProgressListener(getter_AddRefs(browser), getter_AddRefs(manager),
|
||||
getter_AddRefs(managerAsListener))) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWebProgress> webProgress;
|
||||
nsCOMPtr<nsIRequest> request;
|
||||
ReconstructWebProgressAndRequest(manager, aWebProgressData, aRequestData,
|
||||
getter_AddRefs(webProgress),
|
||||
getter_AddRefs(request));
|
||||
|
||||
if (aWebProgressData && aWebProgressData->isTopLevel() &&
|
||||
aSecurityChangeData.isSome()) {
|
||||
Unused << browser->UpdateSecurityUIForSecurityChange(
|
||||
aSecurityChangeData->securityInfo(), aState,
|
||||
aSecurityChangeData->isSecureContext());
|
||||
}
|
||||
|
||||
Unused << managerAsListener->OnSecurityChange(webProgress, request, aState);
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult BrowserParent::RecvNavigationFinished() {
|
||||
nsCOMPtr<nsIBrowser> browser =
|
||||
mFrameElement ? mFrameElement->AsBrowser() : nullptr;
|
||||
|
@ -307,11 +307,6 @@ class BrowserParent final : public PBrowserParent,
|
||||
const RequestData& aRequestData, const nsresult aStatus,
|
||||
const nsString& aMessage);
|
||||
|
||||
mozilla::ipc::IPCResult RecvOnSecurityChange(
|
||||
const Maybe<WebProgressData>& aWebProgressData,
|
||||
const RequestData& aRequestData, const uint32_t aState,
|
||||
const Maybe<WebProgressSecurityChangeData>& aSecurityChangeData);
|
||||
|
||||
mozilla::ipc::IPCResult RecvNotifyContentBlockingEvent(
|
||||
const uint32_t& aEvent, const RequestData& aRequestData,
|
||||
const bool aBlocked, const nsACString& aTrackingOrigin,
|
||||
|
@ -3573,6 +3573,16 @@ bool ContentParent::DeallocPParentToChildStreamParent(
|
||||
return true;
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult ContentParent::RecvAddMixedContentSecurityState(
|
||||
const MaybeDiscarded<WindowContext>& aContext, uint32_t aStateFlags) {
|
||||
if (aContext.IsNullOrDiscarded()) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
aContext.get()->AddMixedContentSecurityState(aStateFlags);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
already_AddRefed<PExternalHelperAppParent>
|
||||
ContentParent::AllocPExternalHelperAppParent(
|
||||
nsIURI* uri, const Maybe<mozilla::net::LoadInfoArgs>& aLoadInfoArgs,
|
||||
|
@ -1063,6 +1063,9 @@ class ContentParent final
|
||||
const MaybeDiscarded<WindowContext>& aContext,
|
||||
WindowContext::BaseTransaction&& aTransaction, uint64_t aEpoch);
|
||||
|
||||
mozilla::ipc::IPCResult RecvAddMixedContentSecurityState(
|
||||
const MaybeDiscarded<WindowContext>& aContext, uint32_t aStateFlags);
|
||||
|
||||
mozilla::ipc::IPCResult RecvFirstIdle();
|
||||
|
||||
mozilla::ipc::IPCResult RecvDeviceReset();
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "mozilla/dom/JSWindowActorBinding.h"
|
||||
#include "mozilla/dom/JSWindowActorParent.h"
|
||||
#include "mozilla/dom/BrowserParent.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/WindowGlobalParent.h"
|
||||
#include "mozilla/dom/MessageManagerBinding.h"
|
||||
|
@ -94,7 +94,6 @@ using mozilla::ScrollAxis from "mozilla/PresShellForwards.h";
|
||||
using mozilla::ScrollFlags from "mozilla/PresShellForwards.h";
|
||||
using struct InputFormData from "mozilla/dom/SessionStoreMessageUtils.h";
|
||||
using struct CollectedInputDataValue from "mozilla/dom/SessionStoreMessageUtils.h";
|
||||
using refcounted class nsITransportSecurityInfo from "nsITransportSecurityInfo.h";
|
||||
using mozilla::ContentBlockingNotifier::StorageAccessGrantedReason from "mozilla/ContentBlockingNotifier.h";
|
||||
using CallerType from "mozilla/dom/BindingDeclarations.h";
|
||||
using mozilla::dom::EmbedderElementEventType from "mozilla/dom/TabMessageUtils.h";
|
||||
@ -154,12 +153,6 @@ struct WebProgressLocationChangeData
|
||||
uint64_t? requestContextID;
|
||||
};
|
||||
|
||||
struct WebProgressSecurityChangeData
|
||||
{
|
||||
nsITransportSecurityInfo securityInfo;
|
||||
bool isSecureContext;
|
||||
};
|
||||
|
||||
/**
|
||||
* A PBrowser manages a maximal locally connected subtree of BrowsingContexts
|
||||
* in a content process.
|
||||
@ -583,10 +576,6 @@ parent:
|
||||
RequestData aRequestData, nsresult aStatus,
|
||||
nsString aMessage);
|
||||
|
||||
async OnSecurityChange(WebProgressData? aWebProgressData,
|
||||
RequestData aRequestData, uint32_t aState,
|
||||
WebProgressSecurityChangeData? aSecurityChangeData);
|
||||
|
||||
async NotifyContentBlockingEvent(uint32_t aEvent, RequestData aRequestData,
|
||||
bool aBlocked, nsCString aTrackingOrigin,
|
||||
nsCString[] aTrackingFullHashes,
|
||||
|
@ -988,6 +988,8 @@ parent:
|
||||
|
||||
async OpenNotificationSettings(Principal principal);
|
||||
|
||||
async AddMixedContentSecurityState(MaybeDiscardedWindowContext aContext, uint32_t aStateFlags);
|
||||
|
||||
// Request that the ServiceWorkerManager in the parent process create a
|
||||
// notification "click" or "close" event and dispatch it on the relevant
|
||||
// ServiceWorker. This needs to happen because when a notification is
|
||||
|
@ -5,6 +5,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include "mozilla/dom/DocShellMessageUtils.h";
|
||||
include "mozilla/ipc/TransportSecurityInfoUtils.h";
|
||||
|
||||
include protocol PBrowser;
|
||||
include protocol PInProcess;
|
||||
@ -21,6 +22,7 @@ using nscolor from "nsColor.h";
|
||||
using refcounted class nsDocShellLoadState from "nsDocShellLoadState.h";
|
||||
using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h";
|
||||
using mozilla::layers::LayersId from "mozilla/layers/LayersTypes.h";
|
||||
using refcounted class nsITransportSecurityInfo from "nsITransportSecurityInfo.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -114,6 +116,8 @@ parent:
|
||||
// Update the document's HTTPS-Only Mode flags in this WindowGlobal.
|
||||
async UpdateHttpsOnlyStatus(uint32_t aHttpsOnlyStatus);
|
||||
|
||||
async UpdateDocumentSecurityInfo(nsITransportSecurityInfo aSecurityInfo);
|
||||
|
||||
/// Send down initial document bit to the parent.
|
||||
async SetIsInitialDocument(bool aIsInitialDocument);
|
||||
|
||||
|
@ -129,11 +129,18 @@ WindowGlobalInit WindowGlobalActor::WindowInitializer(
|
||||
true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsITransportSecurityInfo> securityInfo;
|
||||
if (nsCOMPtr<nsIChannel> channel = doc->GetChannel()) {
|
||||
nsCOMPtr<nsISupports> securityInfoSupports;
|
||||
channel->GetSecurityInfo(getter_AddRefs(securityInfoSupports));
|
||||
securityInfo = do_QueryInterface(securityInfoSupports);
|
||||
}
|
||||
init.securityInfo() = securityInfo;
|
||||
|
||||
// Most data here is specific to the Document, which can change without
|
||||
// creating a new WindowGlobal. Anything new added here which fits that
|
||||
// description should also be synchronized in
|
||||
// WindowGlobalChild::OnNewDocument.
|
||||
|
||||
return init;
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,20 @@ WindowGlobalChild::WindowGlobalChild(dom::WindowContext* aWindowContext,
|
||||
if (!mDocumentURI) {
|
||||
NS_NewURI(getter_AddRefs(mDocumentURI), "about:blank");
|
||||
}
|
||||
|
||||
#ifdef MOZ_GECKO_PROFILER
|
||||
// Registers a DOM Window with the profiler. It re-registers the same Inner
|
||||
// Window ID with different URIs because when a Browsing context is first
|
||||
// loaded, the first url loaded in it will be about:blank. This call keeps the
|
||||
// first non-about:blank registration of window and discards the previous one.
|
||||
uint64_t embedderInnerWindowID = 0;
|
||||
if (BrowsingContext()->GetParent()) {
|
||||
embedderInnerWindowID = BrowsingContext()->GetEmbedderInnerWindowId();
|
||||
}
|
||||
profiler_register_page(BrowsingContext()->Id(), InnerWindowId(),
|
||||
aDocumentURI->GetSpecOrDefault(),
|
||||
embedderInnerWindowID);
|
||||
#endif
|
||||
}
|
||||
|
||||
already_AddRefed<WindowGlobalChild> WindowGlobalChild::Create(
|
||||
@ -165,6 +179,15 @@ void WindowGlobalChild::OnNewDocument(Document* aDocument) {
|
||||
// FIXME: Perhaps these should be combined into a smaller number of messages?
|
||||
SetDocumentURI(aDocument->GetDocumentURI());
|
||||
SetDocumentPrincipal(aDocument->NodePrincipal());
|
||||
|
||||
nsCOMPtr<nsITransportSecurityInfo> securityInfo;
|
||||
if (nsCOMPtr<nsIChannel> channel = aDocument->GetChannel()) {
|
||||
nsCOMPtr<nsISupports> securityInfoSupports;
|
||||
channel->GetSecurityInfo(getter_AddRefs(securityInfoSupports));
|
||||
securityInfo = do_QueryInterface(securityInfoSupports);
|
||||
}
|
||||
SendUpdateDocumentSecurityInfo(securityInfo);
|
||||
|
||||
SendUpdateDocumentCspSettings(aDocument->GetBlockAllMixedContent(false),
|
||||
aDocument->GetUpgradeInsecureRequests(false));
|
||||
SendUpdateSandboxFlags(aDocument->GetSandboxFlags());
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "nsIBrowser.h"
|
||||
#include "nsITransportSecurityInfo.h"
|
||||
#include "nsISharePicker.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
||||
#include "mozilla/dom/DOMException.h"
|
||||
#include "mozilla/dom/DOMExceptionBinding.h"
|
||||
@ -93,6 +94,7 @@ already_AddRefed<WindowGlobalParent> WindowGlobalParent::CreateDisconnected(
|
||||
wgp->mBlockAllMixedContent = aInit.blockAllMixedContent();
|
||||
wgp->mUpgradeInsecureRequests = aInit.upgradeInsecureRequests();
|
||||
wgp->mSandboxFlags = aInit.sandboxFlags();
|
||||
wgp->mSecurityInfo = aInit.securityInfo();
|
||||
net::CookieJarSettings::Deserialize(aInit.cookieJarSettings(),
|
||||
getter_AddRefs(wgp->mCookieJarSettings));
|
||||
MOZ_RELEASE_ASSERT(wgp->mDocumentPrincipal, "Must have a valid principal");
|
||||
@ -594,6 +596,12 @@ mozilla::ipc::IPCResult WindowGlobalParent::RecvUpdateCookieJarSettings(
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult WindowGlobalParent::RecvUpdateDocumentSecurityInfo(
|
||||
nsITransportSecurityInfo* aSecurityInfo) {
|
||||
mSecurityInfo = aSecurityInfo;
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult WindowGlobalParent::RecvShare(
|
||||
IPCWebShareData&& aData, WindowGlobalParent::ShareResolver&& aResolver) {
|
||||
// Widget Layer handoff...
|
||||
@ -717,6 +725,43 @@ already_AddRefed<Promise> WindowGlobalParent::GetSecurityInfo(
|
||||
}
|
||||
|
||||
void WindowGlobalParent::ActorDestroy(ActorDestroyReason aWhy) {
|
||||
if (GetBrowsingContext()->IsTopContent() &&
|
||||
!mDocumentPrincipal->SchemeIs("about")) {
|
||||
// Record the page load
|
||||
uint32_t pageLoaded = 1;
|
||||
Accumulate(Telemetry::MIXED_CONTENT_UNBLOCK_COUNTER, pageLoaded);
|
||||
|
||||
// Record the mixed content status of the docshell in Telemetry
|
||||
enum {
|
||||
NO_MIXED_CONTENT = 0, // There is no Mixed Content on the page
|
||||
MIXED_DISPLAY_CONTENT =
|
||||
1, // The page attempted to load Mixed Display Content
|
||||
MIXED_ACTIVE_CONTENT =
|
||||
2, // The page attempted to load Mixed Active Content
|
||||
MIXED_DISPLAY_AND_ACTIVE_CONTENT = 3 // The page attempted to load Mixed
|
||||
// Display & Mixed Active Content
|
||||
};
|
||||
|
||||
bool hasMixedDisplay =
|
||||
mMixedContentSecurityState &
|
||||
(nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT |
|
||||
nsIWebProgressListener::STATE_BLOCKED_MIXED_DISPLAY_CONTENT);
|
||||
bool hasMixedActive =
|
||||
mMixedContentSecurityState &
|
||||
(nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT |
|
||||
nsIWebProgressListener::STATE_BLOCKED_MIXED_ACTIVE_CONTENT);
|
||||
|
||||
uint32_t mixedContentLevel = NO_MIXED_CONTENT;
|
||||
if (hasMixedDisplay && hasMixedActive) {
|
||||
mixedContentLevel = MIXED_DISPLAY_AND_ACTIVE_CONTENT;
|
||||
} else if (hasMixedActive) {
|
||||
mixedContentLevel = MIXED_ACTIVE_CONTENT;
|
||||
} else if (hasMixedDisplay) {
|
||||
mixedContentLevel = MIXED_DISPLAY_CONTENT;
|
||||
}
|
||||
Accumulate(Telemetry::MIXED_CONTENT_PAGE_LOAD, mixedContentLevel);
|
||||
}
|
||||
|
||||
// If there are any non-discarded nested contexts when this WindowContext is
|
||||
// destroyed, tear them down.
|
||||
nsTArray<RefPtr<dom::BrowsingContext>> toDiscard;
|
||||
@ -828,6 +873,28 @@ bool WindowGlobalParent::ShouldTrackSiteOriginTelemetry() {
|
||||
return DocumentPrincipal()->GetIsContentPrincipal();
|
||||
}
|
||||
|
||||
void WindowGlobalParent::AddMixedContentSecurityState(uint32_t aStateFlags) {
|
||||
MOZ_ASSERT(TopWindowContext() == this);
|
||||
MOZ_ASSERT((aStateFlags &
|
||||
(nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT |
|
||||
nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT |
|
||||
nsIWebProgressListener::STATE_BLOCKED_MIXED_DISPLAY_CONTENT |
|
||||
nsIWebProgressListener::STATE_BLOCKED_MIXED_ACTIVE_CONTENT)) ==
|
||||
aStateFlags,
|
||||
"Invalid flags specified!");
|
||||
|
||||
if ((mMixedContentSecurityState & aStateFlags) ==
|
||||
mMixedContentSecurityState) {
|
||||
return;
|
||||
}
|
||||
|
||||
mMixedContentSecurityState |= aStateFlags;
|
||||
|
||||
if (GetBrowsingContext()->GetCurrentWindowGlobal() == this) {
|
||||
GetBrowsingContext()->UpdateSecurityStateForLocationOrMixedContentChange();
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(WindowGlobalParent, WindowContext,
|
||||
mWindowActors)
|
||||
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include "mozilla/dom/ClientIPCTypes.h"
|
||||
#include "mozilla/dom/DOMRect.h"
|
||||
#include "mozilla/dom/PWindowGlobalParent.h"
|
||||
#include "mozilla/dom/BrowserParent.h"
|
||||
#include "mozilla/dom/WindowContext.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
@ -38,6 +37,7 @@ class CrossProcessPaint;
|
||||
|
||||
namespace dom {
|
||||
|
||||
class BrowserParent;
|
||||
class WindowGlobalChild;
|
||||
class JSWindowActorParent;
|
||||
class JSActorMessageMeta;
|
||||
@ -190,6 +190,13 @@ class WindowGlobalParent final : public WindowContext,
|
||||
|
||||
uint32_t HttpsOnlyStatus() { return mHttpsOnlyStatus; }
|
||||
|
||||
// 'MIXED' state flags, and should only be called on the
|
||||
// top window context.
|
||||
void AddMixedContentSecurityState(uint32_t aStateFlags);
|
||||
uint32_t GetMixedContentSecurityFlags() { return mMixedContentSecurityState; }
|
||||
|
||||
nsITransportSecurityInfo* GetSecurityInfo() { return mSecurityInfo; }
|
||||
|
||||
protected:
|
||||
const nsAString& GetRemoteType() override;
|
||||
JSActor::Type GetSide() override { return JSActor::Type::Parent; }
|
||||
@ -216,6 +223,8 @@ class WindowGlobalParent final : public WindowContext,
|
||||
mIsInitialDocument = aIsInitialDocument;
|
||||
return IPC_OK();
|
||||
}
|
||||
mozilla::ipc::IPCResult RecvUpdateDocumentSecurityInfo(
|
||||
nsITransportSecurityInfo* aSecurityInfo);
|
||||
mozilla::ipc::IPCResult RecvSetHasBeforeUnload(bool aHasBeforeUnload);
|
||||
mozilla::ipc::IPCResult RecvSetClientInfo(
|
||||
const IPCClientInfo& aIPCClientInfo);
|
||||
@ -266,9 +275,13 @@ class WindowGlobalParent final : public WindowContext,
|
||||
// includes the activity log for all of the nested subdocuments as well.
|
||||
ContentBlockingLog mContentBlockingLog;
|
||||
|
||||
uint32_t mMixedContentSecurityState = 0;
|
||||
|
||||
Maybe<ClientInfo> mClientInfo;
|
||||
// Fields being mirrored from the corresponding document
|
||||
nsCOMPtr<nsICookieJarSettings> mCookieJarSettings;
|
||||
nsCOMPtr<nsITransportSecurityInfo> mSecurityInfo;
|
||||
|
||||
uint32_t mSandboxFlags;
|
||||
|
||||
struct OriginCounter {
|
||||
|
@ -4,10 +4,13 @@
|
||||
* 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 "mozilla/ipc/TransportSecurityInfoUtils.h";
|
||||
|
||||
include NeckoChannelParams;
|
||||
include DOMTypes;
|
||||
|
||||
using mozilla::dom::WindowContextInitializer from "mozilla/dom/WindowContext.h";
|
||||
using refcounted class nsITransportSecurityInfo from "nsITransportSecurityInfo.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -26,6 +29,7 @@ struct WindowGlobalInit
|
||||
bool upgradeInsecureRequests;
|
||||
uint32_t sandboxFlags;
|
||||
CookieJarSettingsArgs cookieJarSettings;
|
||||
nsITransportSecurityInfo securityInfo;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -638,17 +638,14 @@ nsresult nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
|
||||
// blocking if the subresource load uses http: and the CSP directive
|
||||
// 'upgrade-insecure-requests' is present on the page.
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell =
|
||||
NS_CP_GetDocShellFromContext(requestingContext);
|
||||
// Carve-out: if we're in the parent and we're loading media, e.g. through
|
||||
// webbrowserpersist, don't reject it if we can't find a docshell.
|
||||
if (XRE_IsParentProcess() && !docShell &&
|
||||
if (XRE_IsParentProcess() && !requestingWindow &&
|
||||
(contentType == TYPE_IMAGE || contentType == TYPE_MEDIA)) {
|
||||
*aDecision = ACCEPT;
|
||||
return NS_OK;
|
||||
}
|
||||
// Otherwise, we must have a docshell
|
||||
NS_ENSURE_TRUE(docShell, NS_OK);
|
||||
// Otherwise, we must have a window
|
||||
NS_ENSURE_TRUE(requestingWindow, NS_OK);
|
||||
|
||||
if (isHttpScheme && aLoadInfo->GetUpgradeInsecureRequests()) {
|
||||
@ -720,44 +717,6 @@ nsresult nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
|
||||
}
|
||||
}
|
||||
|
||||
// Get the root document from the rootShell
|
||||
nsCOMPtr<nsIDocShell> rootShell = topWC->GetBrowsingContext()->GetDocShell();
|
||||
nsCOMPtr<Document> rootDoc = rootShell ? rootShell->GetDocument() : nullptr;
|
||||
|
||||
// TODO Fission: Bug 1631405: Make Mixed Content UI fission compatible
|
||||
// At this point we know it's a mixed content load, which means we we would
|
||||
// allow mixed passive content to load but only allow mixed active content
|
||||
// if the user has updated prefs or overriden mixed content using the UI.
|
||||
// In fission however, we might not have access to the rootShell or RootDoc
|
||||
// so might not be able to access Mixed Content UI. Until we have fixed
|
||||
// Bug 1631405 we assume default behavior and allow mixed passive content
|
||||
// but block mixed active content in fission.
|
||||
if (StaticPrefs::fission_autostart()) {
|
||||
if (!rootShell || !rootDoc) {
|
||||
if (classification == eMixedDisplay) {
|
||||
*aDecision = nsIContentPolicy::ACCEPT;
|
||||
return NS_OK;
|
||||
}
|
||||
// some tests explicitly flip the allow active content pref, so
|
||||
// let's make them work in fission mode.
|
||||
if (!StaticPrefs::security_mixed_content_block_active_content()) {
|
||||
*aDecision = nsIContentPolicy::ACCEPT;
|
||||
return NS_OK;
|
||||
}
|
||||
*aDecision = nsIContentPolicy::REJECT_REQUEST;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISecureBrowserUI> securityUI;
|
||||
rootShell->GetSecurityUI(getter_AddRefs(securityUI));
|
||||
// If there is no securityUI, document doesn't have a security state.
|
||||
// Allow load and return early.
|
||||
if (!securityUI) {
|
||||
*aDecision = nsIContentPolicy::ACCEPT;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
OriginAttributes originAttributes;
|
||||
if (loadingPrincipal) {
|
||||
originAttributes = loadingPrincipal->OriginAttributesRef();
|
||||
@ -844,38 +803,9 @@ nsresult nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
|
||||
: eUserOverride,
|
||||
requestingLocation);
|
||||
|
||||
if (rootDoc->GetMixedContentFlags() == newState) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Copy the new state onto the Document flags.
|
||||
rootDoc->AddMixedContentFlags(newState);
|
||||
|
||||
uint32_t state = nsIWebProgressListener::STATE_IS_BROKEN;
|
||||
MOZ_ALWAYS_SUCCEEDS(securityUI->GetState(&state));
|
||||
|
||||
if (*aDecision == nsIContentPolicy::ACCEPT && rootHasSecureConnection) {
|
||||
// reset state security flag
|
||||
state = state >> 4 << 4;
|
||||
// set state security flag to broken, since there is mixed content
|
||||
state |= nsIWebProgressListener::STATE_IS_BROKEN;
|
||||
|
||||
// If mixed display content is loaded, make sure to include that in the
|
||||
// state.
|
||||
if (rootDoc->GetHasMixedDisplayContentLoaded()) {
|
||||
state |= nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT;
|
||||
}
|
||||
|
||||
// If mixed active content is loaded, make sure to include that in the
|
||||
// state.
|
||||
if (rootDoc->GetHasMixedActiveContentLoaded()) {
|
||||
state |= nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT;
|
||||
}
|
||||
}
|
||||
|
||||
state |= newState;
|
||||
nsDocShell* nativeDocShell = nsDocShell::Cast(docShell);
|
||||
nativeDocShell->nsDocLoader::OnSecurityChange(requestingContext, state);
|
||||
// Notify the top WindowContext of the flags we've computed, and it
|
||||
// will handle updating any relevant security UI.
|
||||
topWC->AddMixedContentSecurityState(newState);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -6,14 +6,11 @@
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIDocShell;
|
||||
interface nsITransportSecurityInfo;
|
||||
|
||||
[scriptable, uuid(718c662a-f810-4a80-a6c9-0b1810ecade2)]
|
||||
[scriptable, builtinclass, uuid(718c662a-f810-4a80-a6c9-0b1810ecade2)]
|
||||
interface nsISecureBrowserUI : nsISupports
|
||||
{
|
||||
void init(in nsIDocShell docShell);
|
||||
|
||||
readonly attribute unsigned long state;
|
||||
readonly attribute bool isSecureContext;
|
||||
readonly attribute nsITransportSecurityInfo secInfo;
|
||||
|
@ -29,12 +29,6 @@ Classes = [
|
||||
'type': 'nsNSSVersion',
|
||||
'headers': ['/security/manager/ssl/nsNSSVersion.h'],
|
||||
},
|
||||
{
|
||||
'cid': '{cc75499a-1dd1-11b2-8a82-ca410ac907b8}',
|
||||
'contract_ids': ['@mozilla.org/secure_browser_ui;1'],
|
||||
'type': 'nsSecureBrowserUIImpl',
|
||||
'headers': ['/security/manager/ssl/nsSecureBrowserUIImpl.h'],
|
||||
},
|
||||
{
|
||||
'cid': '{47402be2-e653-45d0-8daa-9f0dce0ac148}',
|
||||
'contract_ids': ['@mozilla.org/security/local-cert-service;1'],
|
||||
|
@ -73,6 +73,7 @@ EXPORTS += [
|
||||
'nsNSSComponent.h',
|
||||
'nsNSSHelper.h',
|
||||
'nsRandomGenerator.h',
|
||||
'nsSecureBrowserUI.h',
|
||||
'nsSecurityHeaderParser.h',
|
||||
'NSSErrorsService.h',
|
||||
'nsSSLSocketProvider.h',
|
||||
@ -130,7 +131,7 @@ UNIFIED_SOURCES += [
|
||||
'nsPKCS12Blob.cpp',
|
||||
'nsProtectedAuthThread.cpp',
|
||||
'nsRandomGenerator.cpp',
|
||||
'nsSecureBrowserUIImpl.cpp',
|
||||
'nsSecureBrowserUI.cpp',
|
||||
'nsSecurityHeaderParser.cpp',
|
||||
'NSSErrorsService.cpp',
|
||||
'nsSiteSecurityService.cpp',
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include "nsPK11TokenDB.h"
|
||||
#include "nsPKCS11Slot.h"
|
||||
#include "nsRandomGenerator.h"
|
||||
#include "nsSecureBrowserUIImpl.h"
|
||||
#include "nsSecureBrowserUI.h"
|
||||
#include "nsSiteSecurityService.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
|
223
security/manager/ssl/nsSecureBrowserUI.cpp
Normal file
223
security/manager/ssl/nsSecureBrowserUI.cpp
Normal file
@ -0,0 +1,223 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 "nsSecureBrowserUI.h"
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsDocShell.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsITransportSecurityInfo.h"
|
||||
#include "nsIWebProgress.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "mozilla/dom/CanonicalBrowsingContext.h"
|
||||
#include "mozilla/dom/WindowGlobalParent.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsIBrowser.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
LazyLogModule gSecureBrowserUILog("nsSecureBrowserUI");
|
||||
|
||||
nsSecureBrowserUI::nsSecureBrowserUI(CanonicalBrowsingContext* aBrowsingContext)
|
||||
: mState(0) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// The BrowsingContext will own the SecureBrowserUI object, we keep a weak
|
||||
// ref.
|
||||
mBrowsingContextId = aBrowsingContext->Id();
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsSecureBrowserUI, nsISecureBrowserUI,
|
||||
nsISupportsWeakReference)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSecureBrowserUI::GetState(uint32_t* aState) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_ARG(aState);
|
||||
|
||||
MOZ_LOG(gSecureBrowserUILog, LogLevel::Debug,
|
||||
("GetState %p mState: %x", this, mState));
|
||||
*aState = mState;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static bool GetWebProgressListener(CanonicalBrowsingContext* aBrowsingContext,
|
||||
nsIBrowser** aOutBrowser,
|
||||
nsIWebProgress** aOutManager,
|
||||
nsIWebProgressListener** aOutListener) {
|
||||
MOZ_ASSERT(aOutBrowser);
|
||||
MOZ_ASSERT(aOutManager);
|
||||
MOZ_ASSERT(aOutListener);
|
||||
|
||||
nsCOMPtr<nsIBrowser> browser;
|
||||
RefPtr<Element> currentElement = aBrowsingContext->GetEmbedderElement();
|
||||
|
||||
// In Responsive Design Mode, mFrameElement will be the <iframe mozbrowser>,
|
||||
// but we want the <xul:browser> that it is embedded in.
|
||||
while (currentElement) {
|
||||
browser = currentElement->AsBrowser();
|
||||
if (browser) {
|
||||
break;
|
||||
}
|
||||
|
||||
BrowsingContext* browsingContext =
|
||||
currentElement->OwnerDoc()->GetBrowsingContext();
|
||||
currentElement =
|
||||
browsingContext ? browsingContext->GetEmbedderElement() : nullptr;
|
||||
}
|
||||
|
||||
if (!browser) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWebProgress> manager;
|
||||
nsresult rv = browser->GetRemoteWebProgressManager(getter_AddRefs(manager));
|
||||
if (NS_FAILED(rv)) {
|
||||
browser.forget(aOutBrowser);
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWebProgressListener> listener = do_QueryInterface(manager);
|
||||
if (!listener) {
|
||||
// We are no longer remote so we cannot forward this event.
|
||||
browser.forget(aOutBrowser);
|
||||
manager.forget(aOutManager);
|
||||
return true;
|
||||
}
|
||||
|
||||
browser.forget(aOutBrowser);
|
||||
manager.forget(aOutManager);
|
||||
listener.forget(aOutListener);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void nsSecureBrowserUI::UpdateForLocationOrMixedContentChange() {
|
||||
// Our BrowsingContext either has a new WindowGlobalParent, or the
|
||||
// existing one has mutated its security state.
|
||||
// Recompute our security state and fire notifications to listeners
|
||||
|
||||
RefPtr<WindowGlobalParent> win = GetCurrentWindow();
|
||||
mState = nsIWebProgressListener::STATE_IS_INSECURE;
|
||||
|
||||
// Only https is considered secure (it is possible to have e.g. an http URI
|
||||
// with a channel that has a securityInfo that indicates the connection is
|
||||
// secure - e.g. h2/alt-svc or by visiting an http URI over an https proxy).
|
||||
nsCOMPtr<nsITransportSecurityInfo> securityInfo;
|
||||
if (win && win->GetIsSecure()) {
|
||||
securityInfo = win->GetSecurityInfo();
|
||||
if (securityInfo) {
|
||||
MOZ_LOG(gSecureBrowserUILog, LogLevel::Debug,
|
||||
(" we have a security info %p", securityInfo.get()));
|
||||
|
||||
nsresult rv = securityInfo->GetSecurityState(&mState);
|
||||
|
||||
// If the security state is STATE_IS_INSECURE, the TLS handshake never
|
||||
// completed. Don't set any further state.
|
||||
if (NS_SUCCEEDED(rv) &&
|
||||
mState != nsIWebProgressListener::STATE_IS_INSECURE) {
|
||||
MOZ_LOG(gSecureBrowserUILog, LogLevel::Debug,
|
||||
(" set mTopLevelSecurityInfo"));
|
||||
bool isEV;
|
||||
rv = securityInfo->GetIsExtendedValidation(&isEV);
|
||||
if (NS_SUCCEEDED(rv) && isEV) {
|
||||
MOZ_LOG(gSecureBrowserUILog, LogLevel::Debug, (" is EV"));
|
||||
mState |= nsIWebProgressListener::STATE_IDENTITY_EV_TOPLEVEL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add the mixed content flags from the window
|
||||
if (win) {
|
||||
mState |= win->GetMixedContentSecurityFlags();
|
||||
}
|
||||
|
||||
// If we have loaded mixed content and this is a secure page,
|
||||
// then clear secure flags and add broken instead.
|
||||
static const uint32_t kLoadedMixedContentFlags =
|
||||
nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT |
|
||||
nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT;
|
||||
if (win && win->GetIsSecure() && (mState & kLoadedMixedContentFlags)) {
|
||||
// reset state security flag
|
||||
mState = mState >> 4 << 4;
|
||||
// set state security flag to broken, since there is mixed content
|
||||
mState |= nsIWebProgressListener::STATE_IS_BROKEN;
|
||||
}
|
||||
|
||||
RefPtr<CanonicalBrowsingContext> ctx =
|
||||
CanonicalBrowsingContext::Get(mBrowsingContextId);
|
||||
if (!ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This is a bit painful, as we need to do different things for
|
||||
// in-process docshells vs OOP ones.
|
||||
// Ideally we'd just call a function on 'browser' which would
|
||||
// handle sending an event to all listeners, and we wouldn't
|
||||
// need to bother with onSecurityChange.
|
||||
nsCOMPtr<nsIBrowser> browser;
|
||||
nsCOMPtr<nsIWebProgress> manager;
|
||||
nsCOMPtr<nsIWebProgressListener> managerAsListener;
|
||||
if (!GetWebProgressListener(ctx, getter_AddRefs(browser),
|
||||
getter_AddRefs(manager),
|
||||
getter_AddRefs(managerAsListener))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do we need to construct a fake webprogress and request instance?
|
||||
// Should we split this API out of nsIWebProgressListener to avoid
|
||||
// that?
|
||||
if (managerAsListener) {
|
||||
Unused << managerAsListener->OnSecurityChange(nullptr, nullptr, mState);
|
||||
}
|
||||
if (ctx->GetDocShell()) {
|
||||
nsDocShell* nativeDocShell = nsDocShell::Cast(ctx->GetDocShell());
|
||||
nativeDocShell->nsDocLoader::OnSecurityChange(nullptr, mState);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSecureBrowserUI::GetIsSecureContext(bool* aIsSecureContext) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_ARG(aIsSecureContext);
|
||||
|
||||
if (WindowGlobalParent* parent = GetCurrentWindow()) {
|
||||
*aIsSecureContext = parent->GetIsSecureContext();
|
||||
} else {
|
||||
*aIsSecureContext = false;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSecureBrowserUI::GetSecInfo(nsITransportSecurityInfo** result) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_ARG_POINTER(result);
|
||||
|
||||
if (WindowGlobalParent* parent = GetCurrentWindow()) {
|
||||
*result = parent->GetSecurityInfo();
|
||||
}
|
||||
NS_IF_ADDREF(*result);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
WindowGlobalParent* nsSecureBrowserUI::GetCurrentWindow() {
|
||||
RefPtr<CanonicalBrowsingContext> ctx =
|
||||
CanonicalBrowsingContext::Get(mBrowsingContextId);
|
||||
if (!ctx) {
|
||||
return nullptr;
|
||||
}
|
||||
return ctx->GetCurrentWindowGlobal();
|
||||
}
|
@ -18,7 +18,9 @@ class nsIChannel;
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class Document;
|
||||
}
|
||||
class WindowGlobalParent;
|
||||
class CanonicalBrowsingContext;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#define NS_SECURE_BROWSER_UI_CID \
|
||||
@ -28,32 +30,24 @@ class Document;
|
||||
} \
|
||||
}
|
||||
|
||||
class nsSecureBrowserUIImpl : public nsISecureBrowserUI,
|
||||
public nsIWebProgressListener,
|
||||
public nsSupportsWeakReference {
|
||||
class nsSecureBrowserUI : public nsISecureBrowserUI,
|
||||
public nsSupportsWeakReference {
|
||||
public:
|
||||
nsSecureBrowserUIImpl();
|
||||
explicit nsSecureBrowserUI(
|
||||
mozilla::dom::CanonicalBrowsingContext* aBrowsingContext);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
NS_DECL_NSISECUREBROWSERUI
|
||||
|
||||
protected:
|
||||
virtual ~nsSecureBrowserUIImpl() = default;
|
||||
void UpdateForLocationOrMixedContentChange();
|
||||
|
||||
already_AddRefed<mozilla::dom::Document> PrepareForContentChecks();
|
||||
// Do mixed content checks. May update mState.
|
||||
void CheckForMixedContent();
|
||||
// Given some information about a request from an OnLocationChange event,
|
||||
// update mState and mTopLevelSecurityInfo.
|
||||
nsresult UpdateStateAndSecurityInfo(nsIChannel* channel, nsIURI* uri);
|
||||
protected:
|
||||
virtual ~nsSecureBrowserUI() = default;
|
||||
|
||||
mozilla::dom::WindowGlobalParent* GetCurrentWindow();
|
||||
|
||||
uint32_t mState;
|
||||
uint32_t mEvent;
|
||||
bool mIsSecureContext;
|
||||
nsWeakPtr mDocShell;
|
||||
nsWeakPtr mWebProgress;
|
||||
nsCOMPtr<nsITransportSecurityInfo> mTopLevelSecurityInfo;
|
||||
uint64_t mBrowsingContextId;
|
||||
};
|
||||
|
||||
#endif // nsSecureBrowserUIImpl_h
|
@ -1,395 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 "nsSecureBrowserUIImpl.h"
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsDocShell.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsITransportSecurityInfo.h"
|
||||
#include "nsIWebProgress.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
LazyLogModule gSecureBrowserUILog("nsSecureBrowserUI");
|
||||
|
||||
nsSecureBrowserUIImpl::nsSecureBrowserUIImpl()
|
||||
: mState(0), mEvent(0), mIsSecureContext(false) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsSecureBrowserUIImpl, nsISecureBrowserUI,
|
||||
nsIWebProgressListener, nsISupportsWeakReference)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSecureBrowserUIImpl::Init(nsIDocShell* aDocShell) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_ARG(aDocShell);
|
||||
|
||||
aDocShell->SetSecurityUI(this);
|
||||
|
||||
// The Docshell will own the SecureBrowserUI object, we keep a weak ref.
|
||||
nsresult rv;
|
||||
mDocShell = do_GetWeakReference(aDocShell, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// hook up to the webprogress notifications.
|
||||
nsCOMPtr<nsIWebProgress> wp(do_GetInterface(aDocShell));
|
||||
if (!wp) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Save this so we can compare it to the web progress in OnLocationChange.
|
||||
mWebProgress = do_GetWeakReference(wp, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return wp->AddProgressListener(this, nsIWebProgress::NOTIFY_LOCATION);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSecureBrowserUIImpl::GetState(uint32_t* aState) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_ARG(aState);
|
||||
|
||||
MOZ_LOG(gSecureBrowserUILog, LogLevel::Debug, ("GetState %p", this));
|
||||
// With respect to mixed content and tracking protection, we won't know when
|
||||
// the state of our document (or a subdocument) has changed, so we ask the
|
||||
// docShell.
|
||||
CheckForMixedContent();
|
||||
MOZ_LOG(gSecureBrowserUILog, LogLevel::Debug, (" mState: %x", mState));
|
||||
|
||||
*aState = mState;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSecureBrowserUIImpl::GetIsSecureContext(bool* aIsSecureContext) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_ARG(aIsSecureContext);
|
||||
|
||||
*aIsSecureContext = mIsSecureContext;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSecureBrowserUIImpl::GetSecInfo(nsITransportSecurityInfo** result) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_ARG_POINTER(result);
|
||||
|
||||
*result = mTopLevelSecurityInfo;
|
||||
NS_IF_ADDREF(*result);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<dom::Document>
|
||||
nsSecureBrowserUIImpl::PrepareForContentChecks() {
|
||||
nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocShell);
|
||||
if (!docShell) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// For content docShells, the mixed content security state is set on the root
|
||||
// docShell.
|
||||
if (docShell->ItemType() == nsIDocShellTreeItem::typeContent) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem(docShell);
|
||||
nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
|
||||
Unused << docShellTreeItem->GetInProcessSameTypeRootTreeItem(
|
||||
getter_AddRefs(sameTypeRoot));
|
||||
MOZ_ASSERT(
|
||||
sameTypeRoot,
|
||||
"No document shell root tree item from document shell tree item!");
|
||||
docShell = do_QueryInterface(sameTypeRoot);
|
||||
if (!docShell) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<dom::Document> doc = docShell->GetDocument();
|
||||
return doc.forget();
|
||||
}
|
||||
|
||||
// Ask the docShell if we've blocked or loaded any mixed content.
|
||||
void nsSecureBrowserUIImpl::CheckForMixedContent() {
|
||||
RefPtr<dom::Document> doc = PrepareForContentChecks();
|
||||
if (!doc) {
|
||||
// If the docshell has no document, then there is no need to update mState.
|
||||
return;
|
||||
}
|
||||
|
||||
// Has mixed content been loaded or blocked in nsMixedContentBlocker?
|
||||
// This only applies to secure documents even if they're affected by mixed
|
||||
// content blocking in which case the STATE_IS_BROKEN bit would be set rather
|
||||
// than STATE_IS_SECURE.
|
||||
if (((mState & STATE_IS_SECURE) != 0) || ((mState & STATE_IS_BROKEN) != 0)) {
|
||||
if (doc->GetHasMixedActiveContentLoaded()) {
|
||||
mState |= STATE_IS_BROKEN | STATE_LOADED_MIXED_ACTIVE_CONTENT;
|
||||
mState &= ~STATE_IS_SECURE;
|
||||
}
|
||||
|
||||
if (doc->GetHasMixedDisplayContentLoaded()) {
|
||||
mState |= STATE_IS_BROKEN | STATE_LOADED_MIXED_DISPLAY_CONTENT;
|
||||
mState &= ~STATE_IS_SECURE;
|
||||
}
|
||||
|
||||
if (doc->GetHasMixedActiveContentBlocked()) {
|
||||
mState |= STATE_BLOCKED_MIXED_ACTIVE_CONTENT;
|
||||
}
|
||||
|
||||
if (doc->GetHasMixedDisplayContentBlocked()) {
|
||||
mState |= STATE_BLOCKED_MIXED_DISPLAY_CONTENT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to determine if the given URI can be considered secure.
|
||||
// Essentially, only "https" URIs can be considered secure. However, the URI we
|
||||
// have may be e.g. view-source:https://example.com, in which case we have to
|
||||
// evaluate the innermost URI.
|
||||
static nsresult URICanBeConsideredSecure(
|
||||
nsIURI* uri, /* out */ bool& canBeConsideredSecure) {
|
||||
MOZ_ASSERT(uri);
|
||||
NS_ENSURE_ARG(uri);
|
||||
|
||||
canBeConsideredSecure = false;
|
||||
|
||||
nsCOMPtr<nsIURI> innermostURI = NS_GetInnermostURI(uri);
|
||||
if (!innermostURI) {
|
||||
MOZ_LOG(gSecureBrowserUILog, LogLevel::Debug,
|
||||
(" couldn't get innermost URI"));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
MOZ_LOG(gSecureBrowserUILog, LogLevel::Debug,
|
||||
(" innermost URI is '%s'", innermostURI->GetSpecOrDefault().get()));
|
||||
|
||||
canBeConsideredSecure = innermostURI->SchemeIs("https");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Helper function to get the securityInfo from a channel as a
|
||||
// nsITransportSecurityInfo. The out parameter will be set to null if there is
|
||||
// no securityInfo set.
|
||||
static void GetSecurityInfoFromChannel(
|
||||
nsIChannel* channel, nsITransportSecurityInfo** securityInfoOut) {
|
||||
MOZ_ASSERT(channel);
|
||||
MOZ_ASSERT(securityInfoOut);
|
||||
|
||||
NS_ENSURE_TRUE_VOID(channel);
|
||||
NS_ENSURE_TRUE_VOID(securityInfoOut);
|
||||
|
||||
*securityInfoOut = nullptr;
|
||||
|
||||
nsCOMPtr<nsISupports> securityInfoSupports;
|
||||
nsresult rv = channel->GetSecurityInfo(getter_AddRefs(securityInfoSupports));
|
||||
// GetSecurityInfo may return an error, but it's not necessarily fatal - the
|
||||
// underlying channel may simply not have a securityInfo.
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsITransportSecurityInfo> securityInfo(
|
||||
do_QueryInterface(securityInfoSupports));
|
||||
securityInfo.forget(securityInfoOut);
|
||||
}
|
||||
|
||||
nsresult nsSecureBrowserUIImpl::UpdateStateAndSecurityInfo(nsIChannel* channel,
|
||||
nsIURI* uri) {
|
||||
MOZ_ASSERT(channel);
|
||||
MOZ_ASSERT(uri);
|
||||
|
||||
NS_ENSURE_ARG(channel);
|
||||
NS_ENSURE_ARG(uri);
|
||||
|
||||
mState = STATE_IS_INSECURE;
|
||||
mTopLevelSecurityInfo = nullptr;
|
||||
|
||||
// Only https is considered secure (it is possible to have e.g. an http URI
|
||||
// with a channel that has a securityInfo that indicates the connection is
|
||||
// secure - e.g. h2/alt-svc or by visiting an http URI over an https proxy).
|
||||
bool canBeConsideredSecure;
|
||||
nsresult rv = URICanBeConsideredSecure(uri, canBeConsideredSecure);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
if (!canBeConsideredSecure) {
|
||||
MOZ_LOG(gSecureBrowserUILog, LogLevel::Debug,
|
||||
(" URI can't be considered secure"));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsITransportSecurityInfo> securityInfo;
|
||||
GetSecurityInfoFromChannel(channel, getter_AddRefs(securityInfo));
|
||||
if (securityInfo) {
|
||||
MOZ_LOG(gSecureBrowserUILog, LogLevel::Debug,
|
||||
(" we have a security info %p", securityInfo.get()));
|
||||
|
||||
rv = securityInfo->GetSecurityState(&mState);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
// If the security state is STATE_IS_INSECURE, the TLS handshake never
|
||||
// completed. Don't set any further state.
|
||||
if (mState == STATE_IS_INSECURE) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mTopLevelSecurityInfo = securityInfo;
|
||||
MOZ_LOG(gSecureBrowserUILog, LogLevel::Debug,
|
||||
(" set mTopLevelSecurityInfo"));
|
||||
bool isEV;
|
||||
rv = mTopLevelSecurityInfo->GetIsExtendedValidation(&isEV);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
if (isEV) {
|
||||
MOZ_LOG(gSecureBrowserUILog, LogLevel::Debug, (" is EV"));
|
||||
mState |= STATE_IDENTITY_EV_TOPLEVEL;
|
||||
}
|
||||
// Proactively check for mixed content in case GetState() is never called
|
||||
// (this can happen when loading from the BF cache).
|
||||
CheckForMixedContent();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// We receive this notification for the nsIWebProgress we added ourselves to
|
||||
// (i.e. the window we were passed in Init, which should be the top-level
|
||||
// window or whatever corresponds to an <iframe mozbrowser> element). In some
|
||||
// cases, we also receive it from nsIWebProgress instances that are children of
|
||||
// that nsIWebProgress. We ignore notifications from children because they don't
|
||||
// change the top-level state (if children load mixed or tracking content, the
|
||||
// docShell will know and will tell us in GetState when we call
|
||||
// CheckForMixedContent).
|
||||
// When we receive a notification from the top-level nsIWebProgress, we extract
|
||||
// any relevant security information and set our state accordingly. We then call
|
||||
// OnSecurityChange on the docShell corresponding to the nsIWebProgress we were
|
||||
// initialized with to notify any downstream listeners of the security state.
|
||||
NS_IMETHODIMP
|
||||
nsSecureBrowserUIImpl::OnLocationChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest, nsIURI* aLocation,
|
||||
uint32_t aFlags) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
NS_ENSURE_ARG(aWebProgress);
|
||||
NS_ENSURE_ARG(aLocation);
|
||||
|
||||
MOZ_LOG(gSecureBrowserUILog, LogLevel::Debug,
|
||||
("%p OnLocationChange: %p %p %s %x", this, aWebProgress, aRequest,
|
||||
aLocation->GetSpecOrDefault().get(), aFlags));
|
||||
|
||||
// Filter out events from children. See comment at the top of this function.
|
||||
// It would be nice if the attribute isTopLevel worked for this, but that
|
||||
// filters out events for <iframe mozbrowser> elements, which means they don't
|
||||
// get OnSecurityChange events from this implementation. Instead, we check to
|
||||
// see if the web progress we were handed here is the same one as we were
|
||||
// initialized with.
|
||||
nsCOMPtr<nsIWebProgress> originalWebProgress = do_QueryReferent(mWebProgress);
|
||||
if (aWebProgress != originalWebProgress) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If this is a same-document location change, we don't need to update our
|
||||
// state or notify anyone.
|
||||
if (aFlags & LOCATION_CHANGE_SAME_DOCUMENT) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mState = 0;
|
||||
mEvent = 0;
|
||||
mIsSecureContext = false;
|
||||
mTopLevelSecurityInfo = nullptr;
|
||||
|
||||
if (aFlags & LOCATION_CHANGE_ERROR_PAGE) {
|
||||
mState = STATE_IS_INSECURE;
|
||||
mTopLevelSecurityInfo = nullptr;
|
||||
} else {
|
||||
// NB: aRequest may be null. It may also not be QI-able to nsIChannel.
|
||||
nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
|
||||
if (channel) {
|
||||
MOZ_LOG(gSecureBrowserUILog, LogLevel::Debug,
|
||||
(" we have a channel %p", channel.get()));
|
||||
nsresult rv = UpdateStateAndSecurityInfo(channel, aLocation);
|
||||
// Even if this failed, we still want to notify downstream so that we
|
||||
// don't leave a stale security indicator. We set everything to "not
|
||||
// secure" to be safe.
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
MOZ_LOG(gSecureBrowserUILog, LogLevel::Debug,
|
||||
(" Failed to update security info. "
|
||||
"Setting everything to 'not secure' to be safe."));
|
||||
mState = STATE_IS_INSECURE;
|
||||
mTopLevelSecurityInfo = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<mozIDOMWindowProxy> domWindow;
|
||||
aWebProgress->GetDOMWindow(getter_AddRefs(domWindow));
|
||||
if (domWindow) {
|
||||
nsPIDOMWindowOuter* outerWindow = nsPIDOMWindowOuter::From(domWindow);
|
||||
if (outerWindow) {
|
||||
nsGlobalWindowInner* innerWindow =
|
||||
nsGlobalWindowInner::Cast(outerWindow->GetCurrentInnerWindow());
|
||||
if (innerWindow) {
|
||||
mIsSecureContext = innerWindow->IsSecureContext();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocShell);
|
||||
if (docShell) {
|
||||
MOZ_LOG(gSecureBrowserUILog, LogLevel::Debug,
|
||||
(" calling OnSecurityChange %p %x", aRequest, mState));
|
||||
nsDocShell::Cast(docShell)->nsDocLoader::OnSecurityChange(aRequest, mState);
|
||||
} else {
|
||||
MOZ_LOG(gSecureBrowserUILog, LogLevel::Debug, (" no docShell?"));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSecureBrowserUIImpl::OnStateChange(nsIWebProgress*, nsIRequest*, uint32_t,
|
||||
nsresult) {
|
||||
MOZ_ASSERT_UNREACHABLE("Should have been excluded in AddProgressListener()");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSecureBrowserUIImpl::OnProgressChange(nsIWebProgress*, nsIRequest*, int32_t,
|
||||
int32_t, int32_t, int32_t) {
|
||||
MOZ_ASSERT_UNREACHABLE("Should have been excluded in AddProgressListener()");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSecureBrowserUIImpl::OnStatusChange(nsIWebProgress*, nsIRequest*, nsresult,
|
||||
const char16_t*) {
|
||||
MOZ_ASSERT_UNREACHABLE("Should have been excluded in AddProgressListener()");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsSecureBrowserUIImpl::OnSecurityChange(nsIWebProgress*, nsIRequest*,
|
||||
uint32_t) {
|
||||
MOZ_ASSERT_UNREACHABLE("Should have been excluded in AddProgressListener()");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsSecureBrowserUIImpl::OnContentBlockingEvent(nsIWebProgress*,
|
||||
nsIRequest*, uint32_t) {
|
||||
MOZ_ASSERT_UNREACHABLE("Should have been excluded in AddProgressListener()");
|
||||
return NS_OK;
|
||||
}
|
@ -160,17 +160,6 @@ already_AddRefed<nsWebBrowser> nsWebBrowser::Create(
|
||||
|
||||
NS_ENSURE_SUCCESS(docShellAsWin->Create(), nullptr);
|
||||
|
||||
// Hook into the OnSecurityChange() notification for lock/unlock icon
|
||||
// updates
|
||||
// this works because the implementation of nsISecureBrowserUI
|
||||
// (nsSecureBrowserUIImpl) calls docShell->SetSecurityUI(this);
|
||||
nsCOMPtr<nsISecureBrowserUI> securityUI =
|
||||
do_CreateInstance(NS_SECURE_BROWSER_UI_CONTRACTID);
|
||||
if (NS_WARN_IF(!securityUI)) {
|
||||
return nullptr;
|
||||
}
|
||||
securityUI->Init(docShell);
|
||||
|
||||
docShellTreeOwner->AddToWatcher(); // evil twin of Remove in SetDocShell(0)
|
||||
docShellTreeOwner->AddChromeListeners();
|
||||
|
||||
|
@ -361,8 +361,6 @@
|
||||
|
||||
this._unselectedTabHoverMessageListenerCount = 0;
|
||||
|
||||
this._securityUI = null;
|
||||
|
||||
this.urlbarChangeTracker = {
|
||||
_startedLoadSinceLastUserTyping: false,
|
||||
|
||||
@ -894,36 +892,7 @@
|
||||
}
|
||||
|
||||
get securityUI() {
|
||||
if (this.isRemoteBrowser) {
|
||||
if (!this._securityUI) {
|
||||
// Don't attempt to create the remote web progress if the
|
||||
// messageManager has already gone away
|
||||
if (!this.messageManager) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let jsm = "resource://gre/modules/RemoteSecurityUI.jsm";
|
||||
let RemoteSecurityUI = ChromeUtils.import(jsm, {}).RemoteSecurityUI;
|
||||
this._securityUI = new RemoteSecurityUI();
|
||||
}
|
||||
|
||||
// We want to double-wrap the JS implemented interface, so that QI and instanceof works.
|
||||
var ptr = Cc[
|
||||
"@mozilla.org/supports-interface-pointer;1"
|
||||
].createInstance(Ci.nsISupportsInterfacePointer);
|
||||
ptr.data = this._securityUI;
|
||||
return ptr.data.QueryInterface(Ci.nsISecureBrowserUI);
|
||||
}
|
||||
|
||||
if (!this.docShell.securityUI) {
|
||||
const SECUREBROWSERUI_CONTRACTID = "@mozilla.org/secure_browser_ui;1";
|
||||
var securityUI = Cc[SECUREBROWSERUI_CONTRACTID].createInstance(
|
||||
Ci.nsISecureBrowserUI
|
||||
);
|
||||
securityUI.init(this.docShell);
|
||||
}
|
||||
|
||||
return this.docShell.securityUI;
|
||||
return this.browsingContext.secureBrowserUI;
|
||||
}
|
||||
|
||||
set userTypedValue(val) {
|
||||
@ -1349,16 +1318,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
updateSecurityUIForSecurityChange(aSecurityInfo, aState, aIsSecureContext) {
|
||||
if (this.isRemoteBrowser && this.messageManager) {
|
||||
// Invoking this getter triggers the generation of the underlying object,
|
||||
// which we need to access with ._securityUI, because .securityUI returns
|
||||
// a wrapper that makes _update inaccessible.
|
||||
void this.securityUI;
|
||||
this._securityUI._update(aSecurityInfo, aState, aIsSecureContext);
|
||||
}
|
||||
}
|
||||
|
||||
get remoteWebProgressManager() {
|
||||
return this._remoteWebProgressManager;
|
||||
}
|
||||
|
@ -1,33 +0,0 @@
|
||||
// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
|
||||
// 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/.
|
||||
|
||||
var EXPORTED_SYMBOLS = ["RemoteSecurityUI"];
|
||||
|
||||
function RemoteSecurityUI() {
|
||||
this._secInfo = null;
|
||||
this._state = 0;
|
||||
this._isSecureContext = false;
|
||||
}
|
||||
|
||||
RemoteSecurityUI.prototype = {
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsISecureBrowserUI]),
|
||||
|
||||
// nsISecureBrowserUI
|
||||
get state() {
|
||||
return this._state;
|
||||
},
|
||||
get secInfo() {
|
||||
return this._secInfo;
|
||||
},
|
||||
get isSecureContext() {
|
||||
return this._isSecureContext;
|
||||
},
|
||||
|
||||
_update(aSecInfo, aState, aIsSecureContext) {
|
||||
this._secInfo = aSecInfo;
|
||||
this._state = aState;
|
||||
this._isSecureContext = aIsSecureContext;
|
||||
},
|
||||
};
|
@ -117,9 +117,6 @@ with Files('PrivateBrowsingUtils.jsm'):
|
||||
with Files('Promise*.jsm'):
|
||||
BUG_COMPONENT = ('Toolkit', 'Async Tooling')
|
||||
|
||||
with Files('RemoteSecurityUI.jsm'):
|
||||
BUG_COMPONENT = ('Firefox', 'Tabbed Browser')
|
||||
|
||||
with Files('RemoteWebProgress.jsm'):
|
||||
BUG_COMPONENT = ('Core', 'DOM: Navigation')
|
||||
|
||||
@ -212,7 +209,6 @@ EXTRA_JS_MODULES += [
|
||||
'PromiseUtils.jsm',
|
||||
'Region.jsm',
|
||||
'RemotePageAccessManager.jsm',
|
||||
'RemoteSecurityUI.jsm',
|
||||
'RemoteWebProgress.jsm',
|
||||
'ResetProfile.jsm',
|
||||
'ResponsivenessMonitor.jsm',
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "mozilla/dom/WindowGlobalParent.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/BrowserParent.h"
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/SchedulerGroup.h"
|
||||
|
Loading…
Reference in New Issue
Block a user