123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
- /* 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 "DomainPolicy.h"
- #include "mozilla/dom/ContentParent.h"
- #include "mozilla/ipc/URIUtils.h"
- #include "mozilla/Unused.h"
- #include "nsIMessageManager.h"
- #include "nsScriptSecurityManager.h"
- namespace mozilla {
- using namespace ipc;
- using namespace dom;
- NS_IMPL_ISUPPORTS(DomainPolicy, nsIDomainPolicy)
- static nsresult
- BroadcastDomainSetChange(DomainSetType aSetType, DomainSetChangeType aChangeType,
- nsIURI* aDomain = nullptr)
- {
- MOZ_ASSERT(XRE_IsParentProcess(),
- "DomainPolicy should only be exposed to the chrome process.");
- nsTArray<ContentParent*> parents;
- ContentParent::GetAll(parents);
- if (!parents.Length()) {
- return NS_OK;
- }
- OptionalURIParams uri;
- SerializeURI(aDomain, uri);
- for (uint32_t i = 0; i < parents.Length(); i++) {
- Unused << parents[i]->SendDomainSetChanged(aSetType, aChangeType, uri);
- }
- return NS_OK;
- }
- DomainPolicy::DomainPolicy() : mBlacklist(new DomainSet(BLACKLIST))
- , mSuperBlacklist(new DomainSet(SUPER_BLACKLIST))
- , mWhitelist(new DomainSet(WHITELIST))
- , mSuperWhitelist(new DomainSet(SUPER_WHITELIST))
- {
- if (XRE_IsParentProcess()) {
- BroadcastDomainSetChange(NO_TYPE, ACTIVATE_POLICY);
- }
- }
- DomainPolicy::~DomainPolicy()
- {
- // The SSM holds a strong ref to the DomainPolicy until Deactivate() is
- // invoked, so we should never hit the destructor until that happens.
- MOZ_ASSERT(!mBlacklist && !mSuperBlacklist &&
- !mWhitelist && !mSuperWhitelist);
- }
- NS_IMETHODIMP
- DomainPolicy::GetBlacklist(nsIDomainSet** aSet)
- {
- nsCOMPtr<nsIDomainSet> set = mBlacklist.get();
- set.forget(aSet);
- return NS_OK;
- }
- NS_IMETHODIMP
- DomainPolicy::GetSuperBlacklist(nsIDomainSet** aSet)
- {
- nsCOMPtr<nsIDomainSet> set = mSuperBlacklist.get();
- set.forget(aSet);
- return NS_OK;
- }
- NS_IMETHODIMP
- DomainPolicy::GetWhitelist(nsIDomainSet** aSet)
- {
- nsCOMPtr<nsIDomainSet> set = mWhitelist.get();
- set.forget(aSet);
- return NS_OK;
- }
- NS_IMETHODIMP
- DomainPolicy::GetSuperWhitelist(nsIDomainSet** aSet)
- {
- nsCOMPtr<nsIDomainSet> set = mSuperWhitelist.get();
- set.forget(aSet);
- return NS_OK;
- }
- NS_IMETHODIMP
- DomainPolicy::Deactivate()
- {
- // Clear the hashtables first to free up memory, since script might
- // hold the doomed sets alive indefinitely.
- mBlacklist->Clear();
- mSuperBlacklist->Clear();
- mWhitelist->Clear();
- mSuperWhitelist->Clear();
- // Null them out.
- mBlacklist = nullptr;
- mSuperBlacklist = nullptr;
- mWhitelist = nullptr;
- mSuperWhitelist = nullptr;
- // Inform the SSM.
- nsScriptSecurityManager* ssm = nsScriptSecurityManager::GetScriptSecurityManager();
- if (ssm) {
- ssm->DeactivateDomainPolicy();
- }
- if (XRE_IsParentProcess()) {
- BroadcastDomainSetChange(NO_TYPE, DEACTIVATE_POLICY);
- }
- return NS_OK;
- }
- void
- DomainPolicy::CloneDomainPolicy(DomainPolicyClone* aClone)
- {
- aClone->active() = true;
- mBlacklist->CloneSet(&aClone->blacklist());
- mSuperBlacklist->CloneSet(&aClone->superBlacklist());
- mWhitelist->CloneSet(&aClone->whitelist());
- mSuperWhitelist->CloneSet(&aClone->superWhitelist());
- }
- static
- void
- CopyURIs(const InfallibleTArray<URIParams>& aDomains, nsIDomainSet* aSet)
- {
- for (uint32_t i = 0; i < aDomains.Length(); i++) {
- nsCOMPtr<nsIURI> uri = DeserializeURI(aDomains[i]);
- aSet->Add(uri);
- }
- }
- void
- DomainPolicy::ApplyClone(DomainPolicyClone* aClone)
- {
- CopyURIs(aClone->blacklist(), mBlacklist);
- CopyURIs(aClone->whitelist(), mWhitelist);
- CopyURIs(aClone->superBlacklist(), mSuperBlacklist);
- CopyURIs(aClone->superWhitelist(), mSuperWhitelist);
- }
- static already_AddRefed<nsIURI>
- GetCanonicalClone(nsIURI* aURI)
- {
- nsCOMPtr<nsIURI> clone;
- nsresult rv = aURI->Clone(getter_AddRefs(clone));
- NS_ENSURE_SUCCESS(rv, nullptr);
- rv = clone->SetUserPass(EmptyCString());
- NS_ENSURE_SUCCESS(rv, nullptr);
- rv = clone->SetPath(EmptyCString());
- NS_ENSURE_SUCCESS(rv, nullptr);
- return clone.forget();
- }
- NS_IMPL_ISUPPORTS(DomainSet, nsIDomainSet)
- NS_IMETHODIMP
- DomainSet::Add(nsIURI* aDomain)
- {
- nsCOMPtr<nsIURI> clone = GetCanonicalClone(aDomain);
- NS_ENSURE_TRUE(clone, NS_ERROR_FAILURE);
- mHashTable.PutEntry(clone);
- if (XRE_IsParentProcess())
- return BroadcastDomainSetChange(mType, ADD_DOMAIN, aDomain);
- return NS_OK;
- }
- NS_IMETHODIMP
- DomainSet::Remove(nsIURI* aDomain)
- {
- nsCOMPtr<nsIURI> clone = GetCanonicalClone(aDomain);
- NS_ENSURE_TRUE(clone, NS_ERROR_FAILURE);
- mHashTable.RemoveEntry(clone);
- if (XRE_IsParentProcess())
- return BroadcastDomainSetChange(mType, REMOVE_DOMAIN, aDomain);
- return NS_OK;
- }
- NS_IMETHODIMP
- DomainSet::Clear()
- {
- mHashTable.Clear();
- if (XRE_IsParentProcess())
- return BroadcastDomainSetChange(mType, CLEAR_DOMAINS);
- return NS_OK;
- }
- NS_IMETHODIMP
- DomainSet::Contains(nsIURI* aDomain, bool* aContains)
- {
- *aContains = false;
- nsCOMPtr<nsIURI> clone = GetCanonicalClone(aDomain);
- NS_ENSURE_TRUE(clone, NS_ERROR_FAILURE);
- *aContains = mHashTable.Contains(clone);
- return NS_OK;
- }
- NS_IMETHODIMP
- DomainSet::ContainsSuperDomain(nsIURI* aDomain, bool* aContains)
- {
- *aContains = false;
- nsCOMPtr<nsIURI> clone = GetCanonicalClone(aDomain);
- NS_ENSURE_TRUE(clone, NS_ERROR_FAILURE);
- nsAutoCString domain;
- nsresult rv = clone->GetHost(domain);
- NS_ENSURE_SUCCESS(rv, rv);
- while (true) {
- // Check the current domain.
- if (mHashTable.Contains(clone)) {
- *aContains = true;
- return NS_OK;
- }
- // Chop off everything before the first dot, or break if there are no
- // dots left.
- int32_t index = domain.Find(".");
- if (index == kNotFound)
- break;
- domain.Assign(Substring(domain, index + 1));
- rv = clone->SetHost(domain);
- NS_ENSURE_SUCCESS(rv, rv);
- }
- // No match.
- return NS_OK;
- }
- NS_IMETHODIMP
- DomainSet::GetType(uint32_t* aType)
- {
- *aType = mType;
- return NS_OK;
- }
- void
- DomainSet::CloneSet(InfallibleTArray<URIParams>* aDomains)
- {
- for (auto iter = mHashTable.Iter(); !iter.Done(); iter.Next()) {
- nsIURI* key = iter.Get()->GetKey();
- URIParams uri;
- SerializeURI(key, uri);
- aDomains->AppendElement(uri);
- }
- }
- } /* namespace mozilla */
|