Merge inbound to mozilla-central. a=merge

This commit is contained in:
Gurzau Raul 2019-07-17 06:48:50 +03:00
Родитель b34b6dead9 18e9f3ba80
Коммит 21df1f7413
30 изменённых файлов: 285 добавлений и 132 удалений

Просмотреть файл

@ -1396,12 +1396,13 @@ nsAccessibilityService::CreateAccessibleByFrameType(nsIFrame* aFrame,
if (table) {
nsIContent* parentContent =
aContent->GetParentOrHostNode()->AsContent();
aContent->GetParentOrShadowHostNode()->AsContent();
nsIFrame* parentFrame = nullptr;
if (parentContent) {
parentFrame = parentContent->GetPrimaryFrame();
if (!parentFrame || !parentFrame->IsTableWrapperFrame()) {
parentContent = parentContent->GetParentOrHostNode()->AsContent();
parentContent =
parentContent->GetParentOrShadowHostNode()->AsContent();
if (parentContent) {
parentFrame = parentContent->GetPrimaryFrame();
}

Просмотреть файл

@ -43,7 +43,7 @@ function test() {
Services.prefs.clearUserPref(kpkpEnforcementPref);
Services.prefs.clearUserPref(khpkpPinninEnablePref);
let uri = Services.io.newURI("https://" + kPinningDomain);
gSSService.removeState(Ci.nsISiteSecurityService.HEADER_HPKP, uri, 0);
gSSService.resetState(Ci.nsISiteSecurityService.HEADER_HPKP, uri, 0);
});
whenNewTabLoaded(window, loadPinningPage);
}

Просмотреть файл

@ -14,7 +14,7 @@ add_task(async function test_star_redirect() {
let sss = Cc["@mozilla.org/ssservice;1"].getService(
Ci.nsISiteSecurityService
);
sss.removeState(
sss.resetState(
Ci.nsISiteSecurityService.HEADER_HSTS,
NetUtil.newURI("http://example.com/"),
0

Просмотреть файл

@ -54,7 +54,7 @@ function startTest() {
.getService(Ci.nsIIOService);
for (let {url} of TEST_CASES) {
let uri = gIOService.newURI(url);
gSSService.removeState(Ci.nsISiteSecurityService.HEADER_HPKP, uri, 0);
gSSService.resetState(Ci.nsISiteSecurityService.HEADER_HPKP, uri, 0);
}
});

Просмотреть файл

@ -48,7 +48,7 @@ function startTest()
.getService(Ci.nsIIOService);
let uri = gIOService.newURI(TEST_CASES[0].url);
gSSService.removeState(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0);
gSSService.resetState(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0);
});
info("Test detection of HTTP Strict Transport Security.");

Просмотреть файл

@ -759,7 +759,7 @@ static nsINode* FindChromeAccessOnlySubtreeOwner(nsINode* aNode) {
aNode = aNode->GetParentNode();
}
return aNode ? aNode->GetParentOrHostNode() : nullptr;
return aNode ? aNode->GetParentOrShadowHostNode() : nullptr;
}
already_AddRefed<nsINode> FindChromeAccessOnlySubtreeOwner(
@ -990,8 +990,8 @@ void nsIContent::GetEventTargetParent(EventChainPreVisitor& aVisitor) {
// dispatching event to Window object in a content page and
// propagating the event to a chrome Element.
if (targetInKnownToBeHandledScope &&
nsContentUtils::ContentIsShadowIncludingDescendantOf(
this, targetInKnownToBeHandledScope->SubtreeRoot())) {
IsShadowIncludingInclusiveDescendantOf(
targetInKnownToBeHandledScope->SubtreeRoot())) {
// Part of step 11.4.
// "If target's root is a shadow-including inclusive ancestor of
// parent, then"

Просмотреть файл

@ -2200,32 +2200,6 @@ bool nsContentUtils::ContentIsHostIncludingDescendantOf(
return false;
}
bool nsContentUtils::ContentIsShadowIncludingDescendantOf(
const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor) {
MOZ_ASSERT(aPossibleDescendant, "The possible descendant is null!");
MOZ_ASSERT(aPossibleAncestor, "The possible ancestor is null!");
if (aPossibleAncestor == aPossibleDescendant->GetComposedDoc()) {
return true;
}
do {
if (aPossibleDescendant == aPossibleAncestor) {
return true;
}
if (aPossibleDescendant->NodeType() == nsINode::DOCUMENT_FRAGMENT_NODE) {
ShadowRoot* shadowRoot =
ShadowRoot::FromNode(const_cast<nsINode*>(aPossibleDescendant));
aPossibleDescendant = shadowRoot ? shadowRoot->GetHost() : nullptr;
} else {
aPossibleDescendant = aPossibleDescendant->GetParentNode();
}
} while (aPossibleDescendant);
return false;
}
// static
bool nsContentUtils::ContentIsCrossDocDescendantOf(nsINode* aPossibleDescendant,
nsINode* aPossibleAncestor) {
@ -2285,7 +2259,7 @@ nsINode* nsContentUtils::Retarget(nsINode* aTargetA, nsINode* aTargetB) {
}
// or A's root is a shadow-including inclusive ancestor of B...
if (nsContentUtils::ContentIsShadowIncludingDescendantOf(aTargetB, root)) {
if (aTargetB->IsShadowIncludingInclusiveDescendantOf(root)) {
// ...then return A.
return aTargetA;
}

Просмотреть файл

@ -344,13 +344,6 @@ class nsContentUtils {
static bool ContentIsHostIncludingDescendantOf(
const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor);
/**
* Similar to above, but does special case only ShadowRoot,
* not HTMLTemplateElement.
*/
static bool ContentIsShadowIncludingDescendantOf(
const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor);
/**
* Similar to nsINode::IsInclusiveDescendantOf except it crosses document
* boundaries, this function uses ancestor/descendant relations in the

Просмотреть файл

@ -131,6 +131,26 @@ bool nsINode::IsInclusiveDescendantOf(const nsINode* aNode) const {
return false;
}
bool nsINode::IsShadowIncludingInclusiveDescendantOf(
const nsINode* aNode) const {
MOZ_ASSERT(aNode, "The node is nullptr.");
if (this->GetComposedDoc() == aNode) {
return true;
}
const nsINode* node = this;
do {
if (node == aNode) {
return true;
}
node = node->GetParentOrShadowHostNode();
} while (node);
return false;
}
nsINode::nsSlots::nsSlots() : mWeakReference(nullptr) {}
nsINode::nsSlots::~nsSlots() {
@ -261,7 +281,7 @@ nsINode* nsINode::GetRootNode(const GetRootNodeOptions& aOptions) {
return SubtreeRoot();
}
nsINode* nsINode::GetParentOrHostNode() const {
nsINode* nsINode::GetParentOrShadowHostNode() const {
if (mParent) {
return mParent;
}

Просмотреть файл

@ -424,6 +424,13 @@ class nsINode : public mozilla::dom::EventTarget {
*/
bool IsInclusiveDescendantOf(const nsINode* aNode) const;
/**
* https://dom.spec.whatwg.org/#concept-shadow-including-inclusive-descendant
*
* @param aNode must not be nullptr.
*/
bool IsShadowIncludingInclusiveDescendantOf(const nsINode* aNode) const;
/**
* Return this node as a document fragment. Asserts IsDocumentFragment().
*
@ -884,11 +891,7 @@ class nsINode : public mozilla::dom::EventTarget {
*/
nsINode* GetParentNode() const { return mParent; }
/**
* This is similar to above, but in case 'this' is ShadowRoot, we return its
* host element.
*/
nsINode* GetParentOrHostNode() const;
nsINode* GetParentOrShadowHostNode() const;
enum FlattenedParentType { eNotForStyle, eForStyle };

Просмотреть файл

@ -114,6 +114,7 @@ BrowserParent* BrowserBridgeParent::Manager() {
void BrowserBridgeParent::Destroy() {
if (mBrowserParent) {
mBrowserParent->Destroy();
mBrowserParent->SetBrowserBridgeParent(nullptr);
mBrowserParent = nullptr;
}
}

Просмотреть файл

@ -10,6 +10,8 @@
#include "mozilla/dom/CancelContentJSOptionsBinding.h"
#include "mozilla/dom/WindowGlobalParent.h"
#include "nsIObserverService.h"
namespace mozilla {
namespace dom {
@ -68,7 +70,14 @@ void BrowserHost::DestroyComplete() {
}
mRoot->SetOwnerElement(nullptr);
mRoot->Destroy();
mRoot->SetBrowserHost(nullptr);
mRoot = nullptr;
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
if (os) {
os->NotifyObservers(NS_ISUPPORTS_CAST(nsIRemoteTab*, this),
"ipc:browser-destroyed", nullptr);
}
}
bool BrowserHost::Show(const ScreenIntSize& aSize, bool aParentIsActive) {

Просмотреть файл

@ -675,7 +675,6 @@ void BrowserParent::ActorDestroy(ActorDestroyReason why) {
// Tell our embedder that the tab is now going away unless we're an
// out-of-process iframe.
RefPtr<nsFrameLoader> frameLoader = GetFrameLoader(true);
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
if (frameLoader) {
ReceiveMessage(CHILD_PROCESS_SHUTDOWN_MESSAGE, false, nullptr, nullptr,
nullptr);
@ -694,10 +693,6 @@ void BrowserParent::ActorDestroy(ActorDestroyReason why) {
}
mFrameLoader = nullptr;
if (os && mBrowserHost) {
os->NotifyObservers(NS_ISUPPORTS_CAST(nsIRemoteTab*, mBrowserHost),
"ipc:browser-destroyed", nullptr);
}
}
mozilla::ipc::IPCResult BrowserParent::RecvMoveFocus(
@ -3712,20 +3707,18 @@ void BrowserParent::LiveResizeStarted() { SuppressDisplayport(true); }
void BrowserParent::LiveResizeStopped() { SuppressDisplayport(false); }
void BrowserParent::SetBrowserBridgeParent(BrowserBridgeParent* aBrowser) {
// We should not have either a browser bridge or browser host yet
MOZ_ASSERT(!mBrowserBridgeParent);
MOZ_ASSERT(!mBrowserHost);
// We should not have owner content yet
MOZ_ASSERT(!mFrameElement);
// We should either be clearing out our reference to a browser bridge, or not
// have either a browser bridge, browser host, or owner content yet.
MOZ_ASSERT(!aBrowser ||
(!mBrowserBridgeParent && !mBrowserHost && !mFrameElement));
mBrowserBridgeParent = aBrowser;
}
void BrowserParent::SetBrowserHost(BrowserHost* aBrowser) {
// We should not have either a browser bridge or browser host yet
MOZ_ASSERT(!mBrowserBridgeParent);
MOZ_ASSERT(!mBrowserHost);
// We should not have owner content yet
MOZ_ASSERT(!mFrameElement);
// We should either be clearing out our reference to a browser host, or not
// have either a browser bridge, browser host, or owner content yet.
MOZ_ASSERT(!aBrowser ||
(!mBrowserBridgeParent && !mBrowserHost && !mFrameElement));
mBrowserHost = aBrowser;
}

Просмотреть файл

@ -244,8 +244,8 @@ bool SVGUseElement::IsCyclicReferenceTo(const Element& aTarget) const {
if (mOriginal && mOriginal->IsCyclicReferenceTo(aTarget)) {
return true;
}
for (nsINode* parent = GetParentOrHostNode(); parent;
parent = parent->GetParentOrHostNode()) {
for (nsINode* parent = GetParentOrShadowHostNode(); parent;
parent = parent->GetParentOrShadowHostNode()) {
if (parent == &aTarget) {
return true;
}

Просмотреть файл

@ -10048,7 +10048,7 @@ nsresult HTMLEditRules::ConfirmSelectionInBody() {
// XXXsmaug this code is insane.
nsINode* temp = selectionStartPoint.GetContainer();
while (temp && !temp->IsHTMLElement(nsGkAtoms::body)) {
temp = temp->GetParentOrHostNode();
temp = temp->GetParentOrShadowHostNode();
}
// If we aren't in the <body> element, force the issue.
@ -10074,7 +10074,7 @@ nsresult HTMLEditRules::ConfirmSelectionInBody() {
// XXXsmaug this code is insane.
temp = selectionEndPoint.GetContainer();
while (temp && !temp->IsHTMLElement(nsGkAtoms::body)) {
temp = temp->GetParentOrHostNode();
temp = temp->GetParentOrShadowHostNode();
}
// If we aren't in the <body> element, force the issue.

Просмотреть файл

@ -222,8 +222,7 @@ nsresult mozInlineSpellStatus::InitForNavigation(
}
// the anchor node might not be in the DOM anymore, check
if (root && aOldAnchorNode &&
!nsContentUtils::ContentIsShadowIncludingDescendantOf(aOldAnchorNode,
root)) {
!aOldAnchorNode->IsShadowIncludingInclusiveDescendantOf(root)) {
*aContinue = false;
return NS_OK;
}
@ -1271,10 +1270,8 @@ nsresult mozInlineSpellChecker::DoSpellCheck(
// aWordUtil.GetRootNode()
nsINode* rootNode = aWordUtil.GetRootNode();
if (!beginNode->IsInComposedDoc() || !endNode->IsInComposedDoc() ||
!nsContentUtils::ContentIsShadowIncludingDescendantOf(beginNode,
rootNode) ||
!nsContentUtils::ContentIsShadowIncludingDescendantOf(endNode,
rootNode)) {
!beginNode->IsShadowIncludingInclusiveDescendantOf(rootNode) ||
!endNode->IsShadowIncludingInclusiveDescendantOf(rootNode)) {
// Just bail out and don't try to spell-check this
return NS_OK;
}

Просмотреть файл

@ -4725,7 +4725,7 @@ UniquePtr<RangePaintInfo> PresShell::CreateRangePaintInfo(
break;
}
ancestor = ancestor->GetParentOrHostNode();
ancestor = ancestor->GetParentOrShadowHostNode();
}
// use the nearest ancestor frame that includes all continuations as the

Просмотреть файл

@ -1669,7 +1669,7 @@ int32_t nsLayoutUtils::DoCompareTreePosition(
AutoTArray<nsINode*, 32> content1Ancestors;
nsINode* c1;
for (c1 = aContent1; c1 && c1 != aCommonAncestor;
c1 = c1->GetParentOrHostNode()) {
c1 = c1->GetParentOrShadowHostNode()) {
content1Ancestors.AppendElement(c1);
}
if (!c1 && aCommonAncestor) {
@ -1681,7 +1681,7 @@ int32_t nsLayoutUtils::DoCompareTreePosition(
AutoTArray<nsINode*, 32> content2Ancestors;
nsINode* c2;
for (c2 = aContent2; c2 && c2 != aCommonAncestor;
c2 = c2->GetParentOrHostNode()) {
c2 = c2->GetParentOrShadowHostNode()) {
content2Ancestors.AppendElement(c2);
}
if (!c2 && aCommonAncestor) {
@ -1718,7 +1718,7 @@ int32_t nsLayoutUtils::DoCompareTreePosition(
// content1Ancestor != content2Ancestor, so they must be siblings with the
// same parent
nsINode* parent = content1Ancestor->GetParentOrHostNode();
nsINode* parent = content1Ancestor->GetParentOrShadowHostNode();
#ifdef DEBUG
// TODO: remove the uglyness, see bug 598468.
NS_ASSERTION(gPreventAssertInCompareTreePosition || parent,

Просмотреть файл

@ -160,10 +160,13 @@ interface nsISiteSecurityService : nsISupports
[optional] out uint32_t aFailureResult);
/**
* Given a header type, removes state relating to that header of a host,
* Given a header type, resets state relating to that header of a host,
* including the includeSubdomains state that would affect subdomains.
* This essentially removes the state for the domain tree rooted at this
* host.
* host. If any preloaded information is present for that host, that
* information will then be used instead of any other previously existing
* state.
*
* @param aType the type of security state in question
* @param aURI the URI of the target host
* @param aFlags options for this request as defined in nsISocketProvider:
@ -175,10 +178,10 @@ interface nsISiteSecurityService : nsISupports
* happens).
*/
[implicit_jscontext, optional_argc, must_use]
void removeState(in uint32_t aType,
in nsIURI aURI,
in uint32_t aFlags,
[optional] in jsval aOriginAttributes);
void resetState(in uint32_t aType,
in nsIURI aURI,
in uint32_t aFlags,
[optional] in jsval aOriginAttributes);
/**
* Checks whether or not the URI's hostname has a given security state set.

Просмотреть файл

@ -557,11 +557,12 @@ nsresult nsSiteSecurityService::SetHSTSState(
SecurityPropertySource aSource, const OriginAttributes& aOriginAttributes) {
nsAutoCString hostname(aHost);
bool isPreload = (aSource == SourcePreload);
// If max-age is zero, that's an indication to immediately remove the
// security state, so here's a shortcut.
if (!maxage) {
return RemoveStateInternal(aType, hostname, flags, isPreload,
aOriginAttributes);
// If max-age is zero, the host is no longer considered HSTS. If the host was
// preloaded, we store an entry indicating that this host is not HSTS, causing
// the preloaded information to be ignored.
if (maxage == 0) {
return MarkHostAsNotHSTS(aType, hostname, flags, isPreload,
aOriginAttributes);
}
MOZ_ASSERT(
@ -608,28 +609,17 @@ nsresult nsSiteSecurityService::SetHSTSState(
return NS_OK;
}
nsresult nsSiteSecurityService::RemoveStateInternal(
uint32_t aType, nsIURI* aURI, uint32_t aFlags,
const OriginAttributes& aOriginAttributes) {
nsAutoCString hostname;
GetHost(aURI, hostname);
return RemoveStateInternal(aType, hostname, aFlags, false, aOriginAttributes);
}
nsresult nsSiteSecurityService::RemoveStateInternal(
// Helper function to mark a host as not HSTS. In the general case, we can just
// remove the HSTS state. However, for preloaded entries, we have to store an
// entry that indicates this host is not HSTS to prevent the implementation
// using the preloaded information.
nsresult nsSiteSecurityService::MarkHostAsNotHSTS(
uint32_t aType, const nsAutoCString& aHost, uint32_t aFlags,
bool aIsPreload, const OriginAttributes& aOriginAttributes) {
// Child processes are not allowed direct access to this.
if (!XRE_IsParentProcess()) {
MOZ_CRASH(
"Child process: no direct access to "
"nsISiteSecurityService::RemoveStateInternal");
// This only applies to HSTS.
if (aType != nsISiteSecurityService::HEADER_HSTS) {
return NS_ERROR_INVALID_ARG;
}
// Only HSTS is supported at the moment.
NS_ENSURE_TRUE(aType == nsISiteSecurityService::HEADER_HSTS ||
aType == nsISiteSecurityService::HEADER_HPKP,
NS_ERROR_NOT_IMPLEMENTED);
if (aIsPreload && aOriginAttributes != OriginAttributes()) {
return NS_ERROR_INVALID_ARG;
}
@ -638,7 +628,6 @@ nsresult nsSiteSecurityService::RemoveStateInternal(
mozilla::DataStorageType storageType = isPrivate
? mozilla::DataStorage_Private
: mozilla::DataStorage_Persistent;
// If this host is in the preload list, we have to store a knockout entry.
nsAutoCString storageKey;
SetStorageKey(aHost, aType, aOriginAttributes, storageKey);
@ -675,10 +664,18 @@ nsresult nsSiteSecurityService::RemoveStateInternal(
}
NS_IMETHODIMP
nsSiteSecurityService::RemoveState(uint32_t aType, nsIURI* aURI,
uint32_t aFlags,
JS::HandleValue aOriginAttributes,
JSContext* aCx, uint8_t aArgc) {
nsSiteSecurityService::ResetState(uint32_t aType, nsIURI* aURI, uint32_t aFlags,
JS::HandleValue aOriginAttributes,
JSContext* aCx, uint8_t aArgc) {
if (!XRE_IsParentProcess()) {
MOZ_CRASH(
"Child process: no direct access to "
"nsISiteSecurityService::ResetState");
}
if (!aURI) {
return NS_ERROR_INVALID_ARG;
}
OriginAttributes originAttributes;
if (aArgc > 0) {
// OriginAttributes were passed in.
@ -687,7 +684,39 @@ nsSiteSecurityService::RemoveState(uint32_t aType, nsIURI* aURI,
return NS_ERROR_INVALID_ARG;
}
}
return RemoveStateInternal(aType, aURI, aFlags, originAttributes);
return ResetStateInternal(aType, aURI, aFlags, originAttributes);
}
// Helper function to reset stored state of the given type for the host
// identified by the given URI. If there is preloaded information for the host,
// that information will be used for future queries. C.f. MarkHostAsNotHSTS,
// which will store a knockout entry for preloaded HSTS hosts that have sent a
// header with max-age=0 (meaning preloaded information will then not be used
// for that host).
nsresult nsSiteSecurityService::ResetStateInternal(
uint32_t aType, nsIURI* aURI, uint32_t aFlags,
const OriginAttributes& aOriginAttributes) {
if (!aURI) {
return NS_ERROR_INVALID_ARG;
}
if (aType != nsISiteSecurityService::HEADER_HSTS &&
aType != nsISiteSecurityService::HEADER_HPKP) {
return NS_ERROR_INVALID_ARG;
}
nsAutoCString hostname;
nsresult rv = GetHost(aURI, hostname);
if (NS_FAILED(rv)) {
return rv;
}
nsAutoCString storageKey;
SetStorageKey(hostname, aType, aOriginAttributes, storageKey);
bool isPrivate = aFlags & nsISocketProvider::NO_PERMANENT_STORAGE;
mozilla::DataStorageType storageType = isPrivate
? mozilla::DataStorage_Private
: mozilla::DataStorage_Persistent;
mSiteStateStorage->Remove(storageKey, storageType);
return NS_OK;
}
static bool HostIsIPAddress(const nsCString& hostname) {
@ -1062,9 +1091,12 @@ nsresult nsSiteSecurityService::ProcessPKPHeader(
return NS_ERROR_FAILURE;
}
// if maxAge == 0 we must delete all state, for now no hole-punching
// If maxAge == 0, we remove dynamic HPKP state for this host. Due to
// architectural constraints, if this host was preloaded, any future lookups
// will use the preloaded state (i.e. we can't store a "this host is not HPKP"
// entry like we can for HSTS).
if (maxAge == 0) {
return RemoveStateInternal(aType, aSourceURI, aFlags, aOriginAttributes);
return ResetStateInternal(aType, aSourceURI, aFlags, aOriginAttributes);
}
// clamp maxAge to the maximum set by pref

Просмотреть файл

@ -191,11 +191,11 @@ class nsSiteSecurityService : public nsISiteSecurityService,
nsresult SetHPKPState(const char* aHost, SiteHPKPState& entry, uint32_t flags,
bool aIsPreload,
const OriginAttributes& aOriginAttributes);
nsresult RemoveStateInternal(uint32_t aType, nsIURI* aURI, uint32_t aFlags,
const OriginAttributes& aOriginAttributes);
nsresult RemoveStateInternal(uint32_t aType, const nsAutoCString& aHost,
uint32_t aFlags, bool aIsPreload,
const OriginAttributes& aOriginAttributes);
nsresult MarkHostAsNotHSTS(uint32_t aType, const nsAutoCString& aHost,
uint32_t aFlags, bool aIsPreload,
const OriginAttributes& aOriginAttributes);
nsresult ResetStateInternal(uint32_t aType, nsIURI* aURI, uint32_t aFlags,
const OriginAttributes& aOriginAttributes);
bool HostHasHSTSEntry(const nsAutoCString& aHost,
bool aRequireIncludeSubdomains, uint32_t aFlags,
const OriginAttributes& aOriginAttributes,

Просмотреть файл

@ -93,7 +93,7 @@ function test() {
aWin.close();
});
uri = Services.io.newURI("http://localhost");
gSSService.removeState(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0);
gSSService.resetState(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0);
});
// test first when on private mode

Просмотреть файл

@ -69,7 +69,7 @@ function add_tests() {
);
// Clear accumulated state.
ssservice.removeState(Ci.nsISiteSecurityService.HEADER_HPKP, uri, 0);
ssservice.resetState(Ci.nsISiteSecurityService.HEADER_HPKP, uri, 0);
Services.prefs.clearUserPref(
"security.cert_pinning.process_headers_from_non_builtin_roots"
);

Просмотреть файл

@ -55,7 +55,7 @@ function checkPassValidPin(pinValue, settingPin, expectedMaxAge) {
// setup preconditions for the test, if setting ensure there is no previous
// state, if removing ensure there is a valid pin in place.
if (settingPin) {
gSSService.removeState(Ci.nsISiteSecurityService.HEADER_HPKP, uri, 0);
gSSService.resetState(Ci.nsISiteSecurityService.HEADER_HPKP, uri, 0);
} else {
// add a known valid pin!
let validPinValue = "max-age=5000;" + VALID_PIN1 + BACKUP_PIN1;

Просмотреть файл

@ -83,7 +83,7 @@ function doTest(originAttributes1, originAttributes2, shouldShare) {
if (!shouldShare) {
// Remove originAttributes2 from the storage.
sss.removeState(type, uri, 0, originAttributes2);
sss.resetState(type, uri, 0, originAttributes2);
ok(
sss.isSecureURI(type, uri, 0, originAttributes1),
"URI should still be secure given original origin attributes"
@ -91,7 +91,7 @@ function doTest(originAttributes1, originAttributes2, shouldShare) {
}
// Remove originAttributes1 from the storage.
sss.removeState(type, uri, 0, originAttributes1);
sss.resetState(type, uri, 0, originAttributes1);
ok(
!sss.isSecureURI(type, uri, 0, originAttributes1),
"URI should be not be secure after removeState"
@ -161,7 +161,7 @@ function testInvalidOriginAttributes(originAttributes) {
originAttributes
),
() => sss.isSecureURI(type, uri, 0, originAttributes),
() => sss.removeState(type, uri, 0, originAttributes),
() => sss.resetState(type, uri, 0, originAttributes),
];
for (let callback of callbacks) {

Просмотреть файл

@ -0,0 +1,126 @@
// -*- 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/.
"use strict";
// Tests that resetting HSTS/HPKP state in the way the "forget about this site"
// functionality does works as expected for preloaded and non-preloaded sites.
do_get_profile();
var gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService(
Ci.nsIX509CertDB
);
const ROOT_CERT = addCertFromFile(gCertDB, "bad_certs/test-ca.pem", "CTu,,");
var gSSService = Cc["@mozilla.org/ssservice;1"].getService(
Ci.nsISiteSecurityService
);
function run_test() {
Services.prefs.setBoolPref(
"security.cert_pinning.process_headers_from_non_builtin_roots",
true
);
test_removeState(Ci.nsISiteSecurityService.HEADER_HSTS, 0);
test_removeState(
Ci.nsISiteSecurityService.HEADER_HSTS,
Ci.nsISocketProvider.NO_PERMANENT_STORAGE
);
test_removeState(Ci.nsISiteSecurityService.HEADER_HPKP, 0);
test_removeState(
Ci.nsISiteSecurityService.HEADER_HPKP,
Ci.nsISocketProvider.NO_PERMANENT_STORAGE
);
}
function test_removeState(type, flags) {
info(`running test_removeState(type=${type}, flags=${flags})`);
const NON_ISSUED_KEY_HASH = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
const PINNING_ROOT_KEY_HASH = "VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8=";
const PINNING_HEADERS = `pin-sha256="${NON_ISSUED_KEY_HASH}"; pin-sha256="${PINNING_ROOT_KEY_HASH}"`;
let headerAddendum =
type == Ci.nsISiteSecurityService.HEADER_HPKP ? PINNING_HEADERS : "";
let secInfo = new FakeTransportSecurityInfo(
constructCertFromFile("bad_certs/default-ee.pem")
);
// Simulate visiting a non-preloaded site by processing an HSTS or HPKP header
// (depending on which type we were given), check that the HSTS/HPKP bit gets
// set, simulate "forget about this site" (call removeState), and then check
// that the HSTS/HPKP bit isn't set.
let notPreloadedURI = Services.io.newURI("https://not-preloaded.example.com");
ok(!gSSService.isSecureURI(type, notPreloadedURI, flags));
gSSService.processHeader(
type,
notPreloadedURI,
"max-age=1000;" + headerAddendum,
secInfo,
flags,
Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST
);
ok(gSSService.isSecureURI(type, notPreloadedURI, flags));
gSSService.resetState(type, notPreloadedURI, flags);
ok(!gSSService.isSecureURI(type, notPreloadedURI, flags));
// Simulate visiting a non-preloaded site that unsets HSTS/HPKP by processing
// an HSTS/HPKP header with "max-age=0", check that the HSTS/HPKP bit isn't
// set, simulate "forget about this site" (call removeState), and then check
// that the HSTS/HPKP bit isn't set.
gSSService.processHeader(
type,
notPreloadedURI,
"max-age=0;" + headerAddendum,
secInfo,
flags,
Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST
);
ok(!gSSService.isSecureURI(type, notPreloadedURI, flags));
gSSService.resetState(type, notPreloadedURI, flags);
ok(!gSSService.isSecureURI(type, notPreloadedURI, flags));
// Simulate visiting a preloaded site by processing an HSTS/HPKP header, check
// that the HSTS/HPKP bit is still set, simulate "forget about this site"
// (call removeState), and then check that the HSTS/HPKP bit is still set.
let preloadedHost =
type == Ci.nsISiteSecurityService.HEADER_HPKP
? "include-subdomains.pinning.example.com"
: "includesubdomains.preloaded.test";
let preloadedURI = Services.io.newURI(`https://${preloadedHost}`);
ok(gSSService.isSecureURI(type, preloadedURI, flags));
gSSService.processHeader(
type,
preloadedURI,
"max-age=1000;" + headerAddendum,
secInfo,
flags,
Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST
);
ok(gSSService.isSecureURI(type, preloadedURI, flags));
gSSService.resetState(type, preloadedURI, flags);
ok(gSSService.isSecureURI(type, preloadedURI, flags));
// Simulate visiting a preloaded site that unsets HSTS/HPKP by processing an
// HSTS/HPKP header with "max-age=0", check that the HSTS/HPKP bit is what we
// expect (see below), simulate "forget about this site" (call removeState),
// and then check that the HSTS/HPKP bit is set.
gSSService.processHeader(
type,
preloadedURI,
"max-age=0;" + headerAddendum,
secInfo,
flags,
Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST
);
// Due to architectural constraints, encountering a "max-age=0" header for a
// preloaded HPKP site does not mark that site as not HPKP (whereas with HSTS,
// it does).
if (type == Ci.nsISiteSecurityService.HEADER_HPKP) {
ok(gSSService.isSecureURI(type, preloadedURI, flags));
} else {
ok(!gSSService.isSecureURI(type, preloadedURI, flags));
}
gSSService.resetState(type, preloadedURI, flags);
ok(gSSService.isSecureURI(type, preloadedURI, flags));
}

Просмотреть файл

@ -29,7 +29,7 @@ function run_test() {
ok(SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri1, 0));
ok(SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri2, 0));
SSService.removeState(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0);
SSService.resetState(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0);
ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0));
ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri1, 0));
ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri2, 0));

Просмотреть файл

@ -199,6 +199,7 @@ skip-if = toolkit == 'android'
[test_sss_readstate_empty.js]
[test_sss_readstate_garbage.js]
[test_sss_readstate_huge.js]
[test_sss_resetState.js]
[test_sss_savestate.js]
[test_sss_sanitizeOnShutdown.js]
firefox-appdir = browser

Просмотреть файл

@ -705,7 +705,7 @@ class SpecialPowersAPIParent extends JSWindowActorParent {
let sss = Cc["@mozilla.org/ssservice;1"].getService(
Ci.nsISiteSecurityService
);
sss.removeState(Ci.nsISiteSecurityService.HEADER_HSTS, uri, flags);
sss.resetState(Ci.nsISiteSecurityService.HEADER_HSTS, uri, flags);
return undefined;
}

Просмотреть файл

@ -920,14 +920,14 @@ const SecuritySettingsCleaner = {
Ci.nsISiteSecurityService.HEADER_HSTS,
Ci.nsISiteSecurityService.HEADER_HPKP,
]) {
// Also remove HSTS/HPKP/OMS information for subdomains by enumerating
// Also remove HSTS/HPKP information for subdomains by enumerating
// the information in the site security service.
for (let entry of sss.enumerate(type)) {
let hostname = entry.hostname;
if (Services.eTLD.hasRootDomain(hostname, aHost)) {
// This uri is used as a key to remove the state.
// This uri is used as a key to reset the state.
let uri = Services.io.newURI("https://" + hostname);
sss.removeState(type, uri, 0, entry.originAttributes);
sss.resetState(type, uri, 0, entry.originAttributes);
}
}
}