Bug 1526053 - Convert rule models to ES6 classes. r=miker
[gecko.git] / caps / DomainPolicy.cpp
blob484be9b19b7cbea2a979827b349ae9a2f26cd878
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=4 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "DomainPolicy.h"
8 #include "mozilla/dom/ContentParent.h"
9 #include "mozilla/ipc/URIUtils.h"
10 #include "mozilla/Unused.h"
11 #include "nsIMessageManager.h"
12 #include "nsIURIMutator.h"
13 #include "nsScriptSecurityManager.h"
15 namespace mozilla {
17 using namespace ipc;
18 using namespace dom;
20 NS_IMPL_ISUPPORTS(DomainPolicy, nsIDomainPolicy)
22 static nsresult BroadcastDomainSetChange(DomainSetType aSetType,
23 DomainSetChangeType aChangeType,
24 nsIURI* aDomain = nullptr) {
25 MOZ_ASSERT(XRE_IsParentProcess(),
26 "DomainPolicy should only be exposed to the chrome process.");
28 nsTArray<ContentParent*> parents;
29 ContentParent::GetAll(parents);
30 if (!parents.Length()) {
31 return NS_OK;
34 OptionalURIParams uri;
35 SerializeURI(aDomain, uri);
37 for (uint32_t i = 0; i < parents.Length(); i++) {
38 Unused << parents[i]->SendDomainSetChanged(aSetType, aChangeType, uri);
40 return NS_OK;
43 DomainPolicy::DomainPolicy()
44 : mBlocklist(new DomainSet(BLOCKLIST)),
45 mSuperBlocklist(new DomainSet(SUPER_BLOCKLIST)),
46 mAllowlist(new DomainSet(ALLOWLIST)),
47 mSuperAllowlist(new DomainSet(SUPER_ALLOWLIST)) {
48 if (XRE_IsParentProcess()) {
49 BroadcastDomainSetChange(NO_TYPE, ACTIVATE_POLICY);
53 DomainPolicy::~DomainPolicy() {
54 // The SSM holds a strong ref to the DomainPolicy until Deactivate() is
55 // invoked, so we should never hit the destructor until that happens.
56 MOZ_ASSERT(!mBlocklist && !mSuperBlocklist && !mAllowlist &&
57 !mSuperAllowlist);
60 NS_IMETHODIMP
61 DomainPolicy::GetBlocklist(nsIDomainSet** aSet) {
62 nsCOMPtr<nsIDomainSet> set = mBlocklist.get();
63 set.forget(aSet);
64 return NS_OK;
67 NS_IMETHODIMP
68 DomainPolicy::GetSuperBlocklist(nsIDomainSet** aSet) {
69 nsCOMPtr<nsIDomainSet> set = mSuperBlocklist.get();
70 set.forget(aSet);
71 return NS_OK;
74 NS_IMETHODIMP
75 DomainPolicy::GetAllowlist(nsIDomainSet** aSet) {
76 nsCOMPtr<nsIDomainSet> set = mAllowlist.get();
77 set.forget(aSet);
78 return NS_OK;
81 NS_IMETHODIMP
82 DomainPolicy::GetSuperAllowlist(nsIDomainSet** aSet) {
83 nsCOMPtr<nsIDomainSet> set = mSuperAllowlist.get();
84 set.forget(aSet);
85 return NS_OK;
88 NS_IMETHODIMP
89 DomainPolicy::Deactivate() {
90 // Clear the hashtables first to free up memory, since script might
91 // hold the doomed sets alive indefinitely.
92 mBlocklist->Clear();
93 mSuperBlocklist->Clear();
94 mAllowlist->Clear();
95 mSuperAllowlist->Clear();
97 // Null them out.
98 mBlocklist = nullptr;
99 mSuperBlocklist = nullptr;
100 mAllowlist = nullptr;
101 mSuperAllowlist = nullptr;
103 // Inform the SSM.
104 nsScriptSecurityManager* ssm =
105 nsScriptSecurityManager::GetScriptSecurityManager();
106 if (ssm) {
107 ssm->DeactivateDomainPolicy();
109 if (XRE_IsParentProcess()) {
110 BroadcastDomainSetChange(NO_TYPE, DEACTIVATE_POLICY);
112 return NS_OK;
115 void DomainPolicy::CloneDomainPolicy(DomainPolicyClone* aClone) {
116 aClone->active() = true;
117 mBlocklist->CloneSet(&aClone->blocklist());
118 mSuperBlocklist->CloneSet(&aClone->superBlocklist());
119 mAllowlist->CloneSet(&aClone->allowlist());
120 mSuperAllowlist->CloneSet(&aClone->superAllowlist());
123 static void CopyURIs(const InfallibleTArray<URIParams>& aDomains,
124 nsIDomainSet* aSet) {
125 for (uint32_t i = 0; i < aDomains.Length(); i++) {
126 nsCOMPtr<nsIURI> uri = DeserializeURI(aDomains[i]);
127 aSet->Add(uri);
131 void DomainPolicy::ApplyClone(const DomainPolicyClone* aClone) {
132 CopyURIs(aClone->blocklist(), mBlocklist);
133 CopyURIs(aClone->allowlist(), mAllowlist);
134 CopyURIs(aClone->superBlocklist(), mSuperBlocklist);
135 CopyURIs(aClone->superAllowlist(), mSuperAllowlist);
138 static already_AddRefed<nsIURI> GetCanonicalClone(nsIURI* aURI) {
139 nsCOMPtr<nsIURI> clone;
140 nsresult rv = NS_MutateURI(aURI)
141 .SetUserPass(EmptyCString())
142 .SetPathQueryRef(EmptyCString())
143 .Finalize(clone);
144 NS_ENSURE_SUCCESS(rv, nullptr);
145 return clone.forget();
148 NS_IMPL_ISUPPORTS(DomainSet, nsIDomainSet)
150 NS_IMETHODIMP
151 DomainSet::Add(nsIURI* aDomain) {
152 nsCOMPtr<nsIURI> clone = GetCanonicalClone(aDomain);
153 NS_ENSURE_TRUE(clone, NS_ERROR_FAILURE);
154 mHashTable.PutEntry(clone);
155 if (XRE_IsParentProcess())
156 return BroadcastDomainSetChange(mType, ADD_DOMAIN, aDomain);
158 return NS_OK;
161 NS_IMETHODIMP
162 DomainSet::Remove(nsIURI* aDomain) {
163 nsCOMPtr<nsIURI> clone = GetCanonicalClone(aDomain);
164 NS_ENSURE_TRUE(clone, NS_ERROR_FAILURE);
165 mHashTable.RemoveEntry(clone);
166 if (XRE_IsParentProcess())
167 return BroadcastDomainSetChange(mType, REMOVE_DOMAIN, aDomain);
169 return NS_OK;
172 NS_IMETHODIMP
173 DomainSet::Clear() {
174 mHashTable.Clear();
175 if (XRE_IsParentProcess())
176 return BroadcastDomainSetChange(mType, CLEAR_DOMAINS);
178 return NS_OK;
181 NS_IMETHODIMP
182 DomainSet::Contains(nsIURI* aDomain, bool* aContains) {
183 *aContains = false;
184 nsCOMPtr<nsIURI> clone = GetCanonicalClone(aDomain);
185 NS_ENSURE_TRUE(clone, NS_ERROR_FAILURE);
186 *aContains = mHashTable.Contains(clone);
187 return NS_OK;
190 NS_IMETHODIMP
191 DomainSet::ContainsSuperDomain(nsIURI* aDomain, bool* aContains) {
192 *aContains = false;
193 nsCOMPtr<nsIURI> clone = GetCanonicalClone(aDomain);
194 NS_ENSURE_TRUE(clone, NS_ERROR_FAILURE);
195 nsAutoCString domain;
196 nsresult rv = clone->GetHost(domain);
197 NS_ENSURE_SUCCESS(rv, rv);
198 while (true) {
199 // Check the current domain.
200 if (mHashTable.Contains(clone)) {
201 *aContains = true;
202 return NS_OK;
205 // Chop off everything before the first dot, or break if there are no
206 // dots left.
207 int32_t index = domain.Find(".");
208 if (index == kNotFound) break;
209 domain.Assign(Substring(domain, index + 1));
210 rv = NS_MutateURI(clone).SetHost(domain).Finalize(clone);
211 NS_ENSURE_SUCCESS(rv, rv);
214 // No match.
215 return NS_OK;
218 void DomainSet::CloneSet(InfallibleTArray<URIParams>* aDomains) {
219 for (auto iter = mHashTable.Iter(); !iter.Done(); iter.Next()) {
220 nsIURI* key = iter.Get()->GetKey();
222 URIParams uri;
223 SerializeURI(key, uri);
225 aDomains->AppendElement(uri);
229 } /* namespace mozilla */