Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/caps/ContentPrincipal.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=2 sw=2 et 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/. */
6
7
#include "ContentPrincipal.h"
8
9
#include "mozIThirdPartyUtil.h"
10
#include "nsContentUtils.h"
11
#include "nscore.h"
12
#include "nsScriptSecurityManager.h"
13
#include "nsString.h"
14
#include "nsReadableUtils.h"
15
#include "pratom.h"
16
#include "nsIURI.h"
17
#include "nsIURL.h"
18
#include "nsIStandardURL.h"
19
#include "nsIURIWithSpecialOrigin.h"
20
#include "nsIURIMutator.h"
21
#include "nsJSPrincipals.h"
22
#include "nsIEffectiveTLDService.h"
23
#include "nsIClassInfoImpl.h"
24
#include "nsIObjectInputStream.h"
25
#include "nsIObjectOutputStream.h"
26
#include "nsIProtocolHandler.h"
27
#include "nsError.h"
28
#include "nsIContentSecurityPolicy.h"
29
#include "nsNetCID.h"
30
#include "js/Wrapper.h"
31
32
#include "mozilla/dom/BlobURLProtocolHandler.h"
33
#include "mozilla/dom/nsCSPContext.h"
34
#include "mozilla/dom/ScriptSettings.h"
35
#include "mozilla/ClearOnShutdown.h"
36
#include "mozilla/ExtensionPolicyService.h"
37
#include "mozilla/Preferences.h"
38
#include "mozilla/HashFunctions.h"
39
40
using namespace mozilla;
41
42
static inline ExtensionPolicyService&
43
EPS()
44
0
{
45
0
  return ExtensionPolicyService::GetSingleton();
46
0
}
47
48
NS_IMPL_CLASSINFO(ContentPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
49
                  NS_PRINCIPAL_CID)
50
NS_IMPL_QUERY_INTERFACE_CI(ContentPrincipal,
51
                           nsIPrincipal,
52
                           nsISerializable)
53
NS_IMPL_CI_INTERFACE_GETTER(ContentPrincipal,
54
                            nsIPrincipal,
55
                            nsISerializable)
56
57
ContentPrincipal::ContentPrincipal()
58
  : BasePrincipal(eCodebasePrincipal)
59
5.77k
{
60
5.77k
}
61
62
ContentPrincipal::~ContentPrincipal()
63
5.77k
{
64
5.77k
  // let's clear the principal within the csp to avoid a tangling pointer
65
5.77k
  if (mCSP) {
66
0
    static_cast<nsCSPContext*>(mCSP.get())->clearLoadingPrincipal();
67
0
  }
68
5.77k
}
69
70
nsresult
71
ContentPrincipal::Init(nsIURI *aCodebase,
72
                       const OriginAttributes& aOriginAttributes,
73
                       const nsACString& aOriginNoSuffix)
74
5.77k
{
75
5.77k
  NS_ENSURE_ARG(aCodebase);
76
5.77k
77
5.77k
  // Assert that the URI we get here isn't any of the schemes that we know we
78
5.77k
  // should not get here.  These schemes always either inherit their principal
79
5.77k
  // or fall back to a null principal.  These are schemes which return
80
5.77k
  // URI_INHERITS_SECURITY_CONTEXT from their protocol handler's
81
5.77k
  // GetProtocolFlags function.
82
5.77k
  bool hasFlag;
83
5.77k
  Unused << hasFlag; // silence possible compiler warnings.
84
5.77k
  MOZ_DIAGNOSTIC_ASSERT(
85
5.77k
      NS_SUCCEEDED(NS_URIChainHasFlags(aCodebase,
86
5.77k
                                       nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
87
5.77k
                                       &hasFlag)) &&
88
5.77k
      !hasFlag);
89
5.77k
90
5.77k
  mCodebase = aCodebase;
91
5.77k
  FinishInit(aOriginNoSuffix, aOriginAttributes);
92
5.77k
93
5.77k
  return NS_OK;
94
5.77k
}
95
96
nsresult
97
ContentPrincipal::GetScriptLocation(nsACString &aStr)
98
0
{
99
0
  return mCodebase->GetSpec(aStr);
100
0
}
101
102
/* static */ nsresult
103
ContentPrincipal::GenerateOriginNoSuffixFromURI(nsIURI* aURI,
104
                                                nsACString& aOriginNoSuffix)
105
5.77k
{
106
5.77k
  if (!aURI) {
107
0
    return NS_ERROR_FAILURE;
108
0
  }
109
5.77k
110
5.77k
  nsCOMPtr<nsIURI> origin = NS_GetInnermostURI(aURI);
111
5.77k
  if (!origin) {
112
0
    return NS_ERROR_FAILURE;
113
0
  }
114
5.77k
115
5.77k
  MOZ_ASSERT(!NS_IsAboutBlank(origin),
116
5.77k
             "The inner URI for about:blank must be moz-safe-about:blank");
117
5.77k
118
5.77k
  // Handle non-strict file:// uris.
119
5.77k
  if (!nsScriptSecurityManager::GetStrictFileOriginPolicy() &&
120
5.77k
      NS_URIIsLocalFile(origin)) {
121
0
    // If strict file origin policy is not in effect, all local files are
122
0
    // considered to be same-origin, so return a known dummy origin here.
123
0
    aOriginNoSuffix.AssignLiteral("file://UNIVERSAL_FILE_URI_ORIGIN");
124
0
    return NS_OK;
125
0
  }
126
5.77k
127
5.77k
128
5.77k
  nsresult rv;
129
5.77k
// NB: This is only compiled for Thunderbird/Suite.
130
#if IS_ORIGIN_IS_FULL_SPEC_DEFINED
131
  bool fullSpec = false;
132
  rv = NS_URIChainHasFlags(origin, nsIProtocolHandler::ORIGIN_IS_FULL_SPEC, &fullSpec);
133
  NS_ENSURE_SUCCESS(rv, rv);
134
  if (fullSpec) {
135
    return origin->GetAsciiSpec(aOriginNoSuffix);
136
  }
137
#endif
138
139
5.77k
  // We want the invariant that prinA.origin == prinB.origin i.f.f.
140
5.77k
  // prinA.equals(prinB). However, this requires that we impose certain constraints
141
5.77k
  // on the behavior and origin semantics of principals, and in particular, forbid
142
5.77k
  // creating origin strings for principals whose equality constraints are not
143
5.77k
  // expressible as strings (i.e. object equality). Moreover, we want to forbid URIs
144
5.77k
  // containing the magic "^" we use as a separating character for origin
145
5.77k
  // attributes.
146
5.77k
  //
147
5.77k
  // These constraints can generally be achieved by restricting .origin to
148
5.77k
  // nsIStandardURL-based URIs, but there are a few other URI schemes that we need
149
5.77k
  // to handle.
150
5.77k
  bool isBehaved;
151
5.77k
  if ((NS_SUCCEEDED(origin->SchemeIs("about", &isBehaved)) && isBehaved) ||
152
5.77k
      (NS_SUCCEEDED(origin->SchemeIs("moz-safe-about", &isBehaved)) && isBehaved &&
153
5.77k
       // We generally consider two about:foo origins to be same-origin, but
154
5.77k
       // about:blank is special since it can be generated from different sources.
155
5.77k
       // We check for moz-safe-about:blank since origin is an innermost URI.
156
5.77k
       !origin->GetSpecOrDefault().EqualsLiteral("moz-safe-about:blank")) ||
157
5.77k
      (NS_SUCCEEDED(origin->SchemeIs("indexeddb", &isBehaved)) && isBehaved)) {
158
0
    rv = origin->GetAsciiSpec(aOriginNoSuffix);
159
0
    NS_ENSURE_SUCCESS(rv, rv);
160
0
161
0
    int32_t pos = aOriginNoSuffix.FindChar('?');
162
0
    int32_t hashPos = aOriginNoSuffix.FindChar('#');
163
0
164
0
    if (hashPos != kNotFound && (pos == kNotFound || hashPos < pos)) {
165
0
      pos = hashPos;
166
0
    }
167
0
168
0
    if (pos != kNotFound) {
169
0
      aOriginNoSuffix.Truncate(pos);
170
0
    }
171
0
172
0
    // These URIs could technically contain a '^', but they never should.
173
0
    if (NS_WARN_IF(aOriginNoSuffix.FindChar('^', 0) != -1)) {
174
0
      aOriginNoSuffix.Truncate();
175
0
      return NS_ERROR_FAILURE;
176
0
    }
177
0
    return NS_OK;
178
0
  }
179
5.77k
180
5.77k
  // This URL can be a blobURL. In this case, we should use the 'parent'
181
5.77k
  // principal instead.
182
5.77k
  nsCOMPtr<nsIPrincipal> blobPrincipal;
183
5.77k
  if (dom::BlobURLProtocolHandler::GetBlobURLPrincipal(origin,
184
5.77k
                                                       getter_AddRefs(blobPrincipal))) {
185
0
    MOZ_ASSERT(blobPrincipal);
186
0
    return blobPrincipal->GetOriginNoSuffix(aOriginNoSuffix);
187
0
  }
188
5.77k
189
5.77k
  // If we reached this branch, we can only create an origin if we have a
190
5.77k
  // nsIStandardURL.  So, we query to a nsIStandardURL, and fail if we aren't
191
5.77k
  // an instance of an nsIStandardURL nsIStandardURLs have the good property
192
5.77k
  // of escaping the '^' character in their specs, which means that we can be
193
5.77k
  // sure that the caret character (which is reserved for delimiting the end
194
5.77k
  // of the spec, and the beginning of the origin attributes) is not present
195
5.77k
  // in the origin string
196
5.77k
  nsCOMPtr<nsIStandardURL> standardURL = do_QueryInterface(origin);
197
5.77k
  if (!standardURL) {
198
0
    return NS_ERROR_FAILURE;
199
0
  }
200
5.77k
201
5.77k
  // See whether we have a useful hostPort. If we do, use that.
202
5.77k
  nsAutoCString hostPort;
203
5.77k
  bool isChrome = false;
204
5.77k
  rv = origin->SchemeIs("chrome", &isChrome);
205
5.77k
  NS_ENSURE_SUCCESS(rv, rv);
206
5.77k
  if (!isChrome) {
207
5.77k
    rv = origin->GetAsciiHostPort(hostPort);
208
5.77k
    NS_ENSURE_SUCCESS(rv, rv);
209
5.77k
  }
210
5.77k
  if (!hostPort.IsEmpty()) {
211
5.77k
    rv = origin->GetScheme(aOriginNoSuffix);
212
5.77k
    NS_ENSURE_SUCCESS(rv, rv);
213
5.77k
    aOriginNoSuffix.AppendLiteral("://");
214
5.77k
    aOriginNoSuffix.Append(hostPort);
215
5.77k
    return NS_OK;
216
0
  }
217
0
218
0
  rv = aURI->GetAsciiSpec(aOriginNoSuffix);
219
0
  NS_ENSURE_SUCCESS(rv, rv);
220
0
221
0
  // The origin, when taken from the spec, should not contain the ref part of
222
0
  // the URL.
223
0
224
0
  int32_t pos = aOriginNoSuffix.FindChar('?');
225
0
  int32_t hashPos = aOriginNoSuffix.FindChar('#');
226
0
227
0
  if (hashPos != kNotFound && (pos == kNotFound || hashPos < pos)) {
228
0
    pos = hashPos;
229
0
  }
230
0
231
0
  if (pos != kNotFound) {
232
0
    aOriginNoSuffix.Truncate(pos);
233
0
  }
234
0
235
0
  return NS_OK;
236
0
}
237
238
bool
239
ContentPrincipal::SubsumesInternal(nsIPrincipal* aOther,
240
                                   BasePrincipal::DocumentDomainConsideration aConsideration)
241
0
{
242
0
  MOZ_ASSERT(aOther);
243
0
244
0
  // For ContentPrincipal, Subsumes is equivalent to Equals.
245
0
  if (aOther == this) {
246
0
    return true;
247
0
  }
248
0
249
0
  // If either the subject or the object has changed its principal by
250
0
  // explicitly setting document.domain then the other must also have
251
0
  // done so in order to be considered the same origin. This prevents
252
0
  // DNS spoofing based on document.domain (154930)
253
0
  nsresult rv;
254
0
  if (aConsideration == ConsiderDocumentDomain) {
255
0
    // Get .domain on each principal.
256
0
    nsCOMPtr<nsIURI> thisDomain, otherDomain;
257
0
    GetDomain(getter_AddRefs(thisDomain));
258
0
    aOther->GetDomain(getter_AddRefs(otherDomain));
259
0
260
0
    // If either has .domain set, we have equality i.f.f. the domains match.
261
0
    // Otherwise, we fall through to the non-document-domain-considering case.
262
0
    if (thisDomain || otherDomain) {
263
0
      bool isMatch =
264
0
        nsScriptSecurityManager::SecurityCompareURIs(thisDomain, otherDomain);
265
#ifdef DEBUG
266
      if (isMatch) {
267
        nsAutoCString thisSiteOrigin, otherSiteOrigin;
268
        MOZ_ALWAYS_SUCCEEDS(GetSiteOrigin(thisSiteOrigin));
269
        MOZ_ALWAYS_SUCCEEDS(aOther->GetSiteOrigin(otherSiteOrigin));
270
        MOZ_ASSERT(thisSiteOrigin == otherSiteOrigin,
271
          "SubsumesConsideringDomain passed with mismatched siteOrigin!");
272
      }
273
#endif
274
      return isMatch;
275
0
    }
276
0
  }
277
0
278
0
  nsCOMPtr<nsIURI> otherURI;
279
0
  rv = aOther->GetURI(getter_AddRefs(otherURI));
280
0
  NS_ENSURE_SUCCESS(rv, false);
281
0
282
0
  // Compare codebases.
283
0
  return nsScriptSecurityManager::SecurityCompareURIs(mCodebase, otherURI);
284
0
}
285
286
NS_IMETHODIMP
287
ContentPrincipal::GetURI(nsIURI** aURI)
288
5.77k
{
289
5.77k
  NS_ADDREF(*aURI = mCodebase);
290
5.77k
  return NS_OK;
291
5.77k
}
292
293
bool
294
ContentPrincipal::MayLoadInternal(nsIURI* aURI)
295
0
{
296
0
  MOZ_ASSERT(aURI);
297
0
298
#if defined(MOZ_THUNDERBIRD) || defined(MOZ_SUITE)
299
  nsCOMPtr<nsIURIWithSpecialOrigin> uriWithSpecialOrigin = do_QueryInterface(aURI);
300
  if (uriWithSpecialOrigin) {
301
    nsCOMPtr<nsIURI> origin;
302
    nsresult rv = uriWithSpecialOrigin->GetOrigin(getter_AddRefs(origin));
303
    if (NS_WARN_IF(NS_FAILED(rv))) {
304
      return false;
305
    }
306
    MOZ_ASSERT(origin);
307
    OriginAttributes attrs;
308
    RefPtr<BasePrincipal> principal = BasePrincipal::CreateCodebasePrincipal(origin, attrs);
309
    return nsIPrincipal::Subsumes(principal);
310
  }
311
#endif
312
313
0
  nsCOMPtr<nsIPrincipal> blobPrincipal;
314
0
  if (dom::BlobURLProtocolHandler::GetBlobURLPrincipal(aURI,
315
0
                                                       getter_AddRefs(blobPrincipal))) {
316
0
    MOZ_ASSERT(blobPrincipal);
317
0
    return nsIPrincipal::Subsumes(blobPrincipal);
318
0
  }
319
0
320
0
  // If this principal is associated with an addon, check whether that addon
321
0
  // has been given permission to load from this domain.
322
0
  if (AddonAllowsLoad(aURI)) {
323
0
    return true;
324
0
  }
325
0
326
0
  if (nsScriptSecurityManager::SecurityCompareURIs(mCodebase, aURI)) {
327
0
    return true;
328
0
  }
329
0
330
0
  // If strict file origin policy is in effect, local files will always fail
331
0
  // SecurityCompareURIs unless they are identical. Explicitly check file origin
332
0
  // policy, in that case.
333
0
  if (nsScriptSecurityManager::GetStrictFileOriginPolicy() &&
334
0
      NS_URIIsLocalFile(aURI) &&
335
0
      NS_RelaxStrictFileOriginPolicy(aURI, mCodebase)) {
336
0
    return true;
337
0
  }
338
0
339
0
  return false;
340
0
}
341
342
NS_IMETHODIMP
343
ContentPrincipal::GetHashValue(uint32_t* aValue)
344
0
{
345
0
  MOZ_ASSERT(mCodebase, "Need a codebase");
346
0
347
0
  *aValue = nsScriptSecurityManager::HashPrincipalByOrigin(this);
348
0
  return NS_OK;
349
0
}
350
351
NS_IMETHODIMP
352
ContentPrincipal::GetDomain(nsIURI** aDomain)
353
0
{
354
0
  if (!mDomain) {
355
0
    *aDomain = nullptr;
356
0
    return NS_OK;
357
0
  }
358
0
359
0
  NS_ADDREF(*aDomain = mDomain);
360
0
  return NS_OK;
361
0
}
362
363
NS_IMETHODIMP
364
ContentPrincipal::SetDomain(nsIURI* aDomain)
365
0
{
366
0
  MOZ_ASSERT(aDomain);
367
0
368
0
  mDomain = aDomain;
369
0
  SetHasExplicitDomain();
370
0
371
0
  // Recompute all wrappers between compartments using this principal and other
372
0
  // non-chrome compartments.
373
0
  AutoSafeJSContext cx;
374
0
  JSPrincipals *principals = nsJSPrincipals::get(static_cast<nsIPrincipal*>(this));
375
0
  bool success = js::RecomputeWrappers(cx, js::ContentCompartmentsOnly(),
376
0
                                       js::CompartmentsWithPrincipals(principals));
377
0
  NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
378
0
  success = js::RecomputeWrappers(cx, js::CompartmentsWithPrincipals(principals),
379
0
                                  js::ContentCompartmentsOnly());
380
0
  NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
381
0
382
0
  // Set the changed-document-domain flag on compartments containing realms
383
0
  // using this principal.
384
0
  auto cb = [](JSContext*, void*, JS::Handle<JS::Realm*> aRealm) {
385
0
    JS::Compartment* comp = JS::GetCompartmentForRealm(aRealm);
386
0
    xpc::SetCompartmentChangedDocumentDomain(comp);
387
0
  };
388
0
  JS::IterateRealmsWithPrincipals(cx, principals, nullptr, cb);
389
0
390
0
  return NS_OK;
391
0
}
392
393
static nsresult
394
GetBaseDomainHelper(const nsCOMPtr<nsIURI>& aCodebase,
395
                    bool* aHasBaseDomain,
396
                    nsACString& aBaseDomain)
397
0
{
398
0
  *aHasBaseDomain = false;
399
0
400
0
  // For a file URI, we return the file path.
401
0
  if (NS_URIIsLocalFile(aCodebase)) {
402
0
    nsCOMPtr<nsIURL> url = do_QueryInterface(aCodebase);
403
0
404
0
    if (url) {
405
0
      return url->GetFilePath(aBaseDomain);
406
0
    }
407
0
  }
408
0
409
0
  bool hasNoRelativeFlag;
410
0
  nsresult rv = NS_URIChainHasFlags(aCodebase,
411
0
                                    nsIProtocolHandler::URI_NORELATIVE,
412
0
                                    &hasNoRelativeFlag);
413
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
414
0
    return rv;
415
0
  }
416
0
417
0
  if (hasNoRelativeFlag) {
418
0
    return aCodebase->GetSpec(aBaseDomain);
419
0
  }
420
0
421
0
  *aHasBaseDomain = true;
422
0
423
0
  // For everything else, we ask the TLD service via
424
0
  // the ThirdPartyUtil.
425
0
  nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
426
0
    do_GetService(THIRDPARTYUTIL_CONTRACTID);
427
0
  if (thirdPartyUtil) {
428
0
    return thirdPartyUtil->GetBaseDomain(aCodebase, aBaseDomain);
429
0
  }
430
0
431
0
  return NS_OK;
432
0
}
433
434
NS_IMETHODIMP
435
ContentPrincipal::GetBaseDomain(nsACString& aBaseDomain)
436
0
{
437
0
  bool hasBaseDomain;
438
0
  return GetBaseDomainHelper(mCodebase, &hasBaseDomain, aBaseDomain);
439
0
}
440
441
NS_IMETHODIMP
442
ContentPrincipal::GetSiteOrigin(nsACString& aSiteOrigin)
443
0
{
444
0
  // Determine our base domain.
445
0
  bool hasBaseDomain;
446
0
  nsAutoCString baseDomain;
447
0
  nsresult rv = GetBaseDomainHelper(mCodebase, &hasBaseDomain, baseDomain);
448
0
  NS_ENSURE_SUCCESS(rv, rv);
449
0
450
0
  if (!hasBaseDomain) {
451
0
    // This is a special URI ("file:", "about:", "view-source:", etc). Just
452
0
    // return the origin.
453
0
    return GetOrigin(aSiteOrigin);
454
0
  }
455
0
456
0
  // NOTE: Calling `SetHostPort` with a portless domain is insufficient to clear
457
0
  // the port, so an extra `SetPort` call has to be made.
458
0
  nsCOMPtr<nsIURI> siteUri;
459
0
  rv = NS_MutateURI(mCodebase)
460
0
    .SetUserPass(EmptyCString())
461
0
    .SetPort(-1)
462
0
    .SetHostPort(baseDomain)
463
0
    .Finalize(siteUri);
464
0
  MOZ_ASSERT(NS_SUCCEEDED(rv), "failed to create siteUri");
465
0
  NS_ENSURE_SUCCESS(rv, rv);
466
0
467
0
  rv = GenerateOriginNoSuffixFromURI(siteUri, aSiteOrigin);
468
0
  MOZ_ASSERT(NS_SUCCEEDED(rv), "failed to create siteOriginNoSuffix");
469
0
  NS_ENSURE_SUCCESS(rv, rv);
470
0
471
0
  nsAutoCString suffix;
472
0
  rv = GetOriginSuffix(suffix);
473
0
  MOZ_ASSERT(NS_SUCCEEDED(rv), "failed to create suffix");
474
0
  NS_ENSURE_SUCCESS(rv, rv);
475
0
476
0
  aSiteOrigin.Append(suffix);
477
0
  return NS_OK;
478
0
}
479
480
nsresult
481
ContentPrincipal::GetSiteIdentifier(SiteIdentifier& aSite)
482
0
{
483
0
  nsCString siteOrigin;
484
0
  nsresult rv = GetSiteOrigin(siteOrigin);
485
0
  NS_ENSURE_SUCCESS(rv, rv);
486
0
487
0
  RefPtr<BasePrincipal> principal = CreateCodebasePrincipal(siteOrigin);
488
0
  if (!principal) {
489
0
    NS_WARNING("could not instantiate codebase principal");
490
0
    return NS_ERROR_FAILURE;
491
0
  }
492
0
493
0
  aSite.Init(principal);
494
0
  return NS_OK;
495
0
}
496
497
WebExtensionPolicy*
498
ContentPrincipal::AddonPolicy()
499
0
{
500
0
  if (!mAddon.isSome()) {
501
0
    NS_ENSURE_TRUE(mCodebase, nullptr);
502
0
503
0
    bool isMozExt;
504
0
    if (NS_SUCCEEDED(mCodebase->SchemeIs("moz-extension", &isMozExt)) && isMozExt) {
505
0
      mAddon.emplace(EPS().GetByURL(mCodebase.get()));
506
0
    } else {
507
0
      mAddon.emplace(nullptr);
508
0
    }
509
0
  }
510
0
511
0
  return mAddon.value();
512
0
}
513
514
NS_IMETHODIMP
515
ContentPrincipal::GetAddonId(nsAString& aAddonId)
516
0
{
517
0
  auto policy = AddonPolicy();
518
0
  if (policy) {
519
0
    policy->GetId(aAddonId);
520
0
  } else {
521
0
    aAddonId.Truncate();
522
0
  }
523
0
  return NS_OK;
524
0
}
525
526
NS_IMETHODIMP
527
ContentPrincipal::Read(nsIObjectInputStream* aStream)
528
0
{
529
0
  nsCOMPtr<nsISupports> supports;
530
0
  nsCOMPtr<nsIURI> codebase;
531
0
  nsresult rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
532
0
  if (NS_FAILED(rv)) {
533
0
    return rv;
534
0
  }
535
0
536
0
  codebase = do_QueryInterface(supports);
537
0
  // Enforce re-parsing about: URIs so that if they change, we continue to use
538
0
  // their new principals correctly.
539
0
  bool isAbout = false;
540
0
  if (NS_SUCCEEDED(codebase->SchemeIs("about", &isAbout)) && isAbout) {
541
0
    nsAutoCString spec;
542
0
    codebase->GetSpec(spec);
543
0
    NS_ENSURE_SUCCESS(NS_NewURI(getter_AddRefs(codebase), spec), NS_ERROR_FAILURE);
544
0
  }
545
0
546
0
  nsCOMPtr<nsIURI> domain;
547
0
  rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
548
0
  if (NS_FAILED(rv)) {
549
0
    return rv;
550
0
  }
551
0
552
0
  domain = do_QueryInterface(supports);
553
0
554
0
  nsAutoCString suffix;
555
0
  rv = aStream->ReadCString(suffix);
556
0
  NS_ENSURE_SUCCESS(rv, rv);
557
0
558
0
  OriginAttributes attrs;
559
0
  bool ok = attrs.PopulateFromSuffix(suffix);
560
0
  NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
561
0
562
0
  rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
563
0
  NS_ENSURE_SUCCESS(rv, rv);
564
0
565
0
  nsAutoCString originNoSuffix;
566
0
  rv = GenerateOriginNoSuffixFromURI(codebase, originNoSuffix);
567
0
  NS_ENSURE_SUCCESS(rv, rv);
568
0
569
0
  rv = Init(codebase, attrs, originNoSuffix);
570
0
  NS_ENSURE_SUCCESS(rv, rv);
571
0
572
0
  mCSP = do_QueryInterface(supports, &rv);
573
0
  // make sure setRequestContext is called after Init(),
574
0
  // to make sure  the principals URI been initalized.
575
0
  if (mCSP) {
576
0
    mCSP->SetRequestContext(nullptr, this);
577
0
  }
578
0
579
0
  // Note: we don't call SetDomain here because we don't need the wrapper
580
0
  // recomputation code there (we just created this principal).
581
0
  mDomain = domain;
582
0
  if (mDomain) {
583
0
    SetHasExplicitDomain();
584
0
  }
585
0
586
0
  return NS_OK;
587
0
}
588
589
NS_IMETHODIMP
590
ContentPrincipal::Write(nsIObjectOutputStream* aStream)
591
0
{
592
0
  NS_ENSURE_STATE(mCodebase);
593
0
  nsresult rv = NS_WriteOptionalCompoundObject(aStream, mCodebase, NS_GET_IID(nsIURI),
594
0
                                               true);
595
0
  if (NS_FAILED(rv)) {
596
0
    return rv;
597
0
  }
598
0
599
0
  rv = NS_WriteOptionalCompoundObject(aStream, mDomain, NS_GET_IID(nsIURI),
600
0
                                      true);
601
0
  if (NS_FAILED(rv)) {
602
0
    return rv;
603
0
  }
604
0
605
0
  nsAutoCString suffix;
606
0
  OriginAttributesRef().CreateSuffix(suffix);
607
0
608
0
  rv = aStream->WriteStringZ(suffix.get());
609
0
  NS_ENSURE_SUCCESS(rv, rv);
610
0
611
0
  rv = NS_WriteOptionalCompoundObject(aStream, mCSP,
612
0
                                      NS_GET_IID(nsIContentSecurityPolicy),
613
0
                                      true);
614
0
  if (NS_FAILED(rv)) {
615
0
    return rv;
616
0
  }
617
0
618
0
  return NS_OK;
619
0
}