tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

PolicyContainer.cpp (6617B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 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/. */
      6 
      7 #include "PolicyContainer.h"
      8 
      9 #include "mozilla/dom/IntegrityPolicy.h"
     10 #include "mozilla/dom/nsCSPContext.h"
     11 #include "mozilla/ipc/PBackgroundSharedTypes.h"
     12 #include "nsIClassInfoImpl.h"
     13 #include "nsIObjectInputStream.h"
     14 #include "nsIObjectOutputStream.h"
     15 
     16 using namespace mozilla;
     17 using namespace mozilla::dom;
     18 
     19 PolicyContainer::~PolicyContainer() = default;
     20 
     21 constexpr static uint32_t kPolicyContainerSerializationVersion = 1;
     22 
     23 NS_IMETHODIMP
     24 PolicyContainer::Read(nsIObjectInputStream* aStream) {
     25  // Currently, we don't care about the version, but we might in the future.
     26  uint32_t version = 0;
     27  nsresult rv = aStream->Read32(&version);
     28  NS_ENSURE_SUCCESS(rv, rv);
     29 
     30  if (version != kPolicyContainerSerializationVersion) {
     31    return NS_ERROR_FAILURE;
     32  }
     33 
     34  auto ReadOptionalCSPObject = [aStream](nsISupports** aOutCSP) {
     35    bool nonnull = false;
     36    nsresult rv = aStream->ReadBoolean(&nonnull);
     37    NS_ENSURE_SUCCESS(rv, rv);
     38 
     39    if (nonnull) {
     40      nsCID cid;
     41      rv = aStream->ReadID(&cid);
     42      NS_ENSURE_SUCCESS(rv, rv);
     43      MOZ_ASSERT(cid.Equals(nsCSPContext::GetCID()),
     44                 "Expected nsCSPContext CID");
     45 
     46      nsIID iid;
     47      rv = aStream->ReadID(&iid);
     48      NS_ENSURE_SUCCESS(rv, rv);
     49      MOZ_ASSERT(iid.Equals(NS_GET_IID(nsIContentSecurityPolicy)),
     50                 "Expected nsIContentSecurityPolicy IID");
     51 
     52      RefPtr<nsCSPContext> csp = new nsCSPContext();
     53      rv = csp->PolicyContainerRead(aStream);
     54      NS_ENSURE_SUCCESS(rv, rv);
     55      csp.forget(aOutCSP);
     56    }
     57 
     58    return NS_OK;
     59  };
     60 
     61  nsCOMPtr<nsISupports> csp;
     62  rv = ReadOptionalCSPObject(getter_AddRefs(csp));
     63  NS_ENSURE_SUCCESS(rv, rv);
     64  mCSP = do_QueryInterface(csp);
     65 
     66  nsCOMPtr<nsISupports> integrityPolicy;
     67  rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(integrityPolicy));
     68  NS_ENSURE_SUCCESS(rv, rv);
     69  mIntegrityPolicy = do_QueryInterface(integrityPolicy);
     70  return NS_OK;
     71 }
     72 
     73 NS_IMETHODIMP
     74 PolicyContainer::Write(nsIObjectOutputStream* aStream) {
     75  aStream->Write32(kPolicyContainerSerializationVersion);
     76 
     77  nsresult rv = NS_WriteOptionalCompoundObject(
     78      aStream, mCSP, NS_GET_IID(nsIContentSecurityPolicy), true);
     79  NS_ENSURE_SUCCESS(rv, rv);
     80 
     81  rv = NS_WriteOptionalCompoundObject(aStream, mIntegrityPolicy,
     82                                      NS_GET_IID(nsIIntegrityPolicy), true);
     83  NS_ENSURE_SUCCESS(rv, rv);
     84 
     85  return NS_OK;
     86 }
     87 
     88 void PolicyContainer::ToArgs(const PolicyContainer* aPolicy,
     89                             mozilla::ipc::PolicyContainerArgs& aArgs) {
     90  if (!aPolicy) {
     91    return;
     92  }
     93 
     94  if (aPolicy->mCSP) {
     95    mozilla::ipc::CSPInfo cspInfo;
     96    mozilla::ipc::CSPToCSPInfo(aPolicy->mCSP, &cspInfo);
     97    aArgs.csp() = Some(cspInfo);
     98  }
     99 
    100  if (aPolicy->mIntegrityPolicy) {
    101    mozilla::ipc::IntegrityPolicyArgs integrityPolicyArgs;
    102    IntegrityPolicy::ToArgs(IntegrityPolicy::Cast(aPolicy->mIntegrityPolicy),
    103                            integrityPolicyArgs);
    104    aArgs.integrityPolicy() = Some(integrityPolicyArgs);
    105  }
    106 }
    107 
    108 void PolicyContainer::FromArgs(const mozilla::ipc::PolicyContainerArgs& aArgs,
    109                               mozilla::dom::Document* aRequestingDocument,
    110                               PolicyContainer** aPolicy) {
    111  RefPtr<PolicyContainer> policy = new PolicyContainer();
    112 
    113  if (aArgs.csp().isSome()) {
    114    nsCOMPtr<nsIContentSecurityPolicy> csp =
    115        mozilla::ipc::CSPInfoToCSP(*aArgs.csp(), aRequestingDocument);
    116    policy->SetCSP(nsCSPContext::Cast(csp));
    117  }
    118 
    119  if (aArgs.integrityPolicy().isSome()) {
    120    RefPtr<dom::IntegrityPolicy> integrityPolicy = new dom::IntegrityPolicy();
    121    IntegrityPolicy::FromArgs(*aArgs.integrityPolicy(),
    122                              getter_AddRefs(integrityPolicy));
    123    policy->SetIntegrityPolicy(integrityPolicy);
    124  }
    125 
    126  policy.forget(aPolicy);
    127 }
    128 
    129 void PolicyContainer::InitFromOther(PolicyContainer* aOther) {
    130  if (!aOther) {
    131    return;
    132  }
    133 
    134  if (aOther->mCSP) {
    135    RefPtr<nsCSPContext> csp = new nsCSPContext();
    136    csp = new nsCSPContext();
    137    csp->InitFromOther(nsCSPContext::Cast(aOther->mCSP));
    138    mCSP = csp;
    139  }
    140 
    141  if (aOther->mIntegrityPolicy) {
    142    RefPtr<dom::IntegrityPolicy> integrityPolicy = new dom::IntegrityPolicy();
    143    integrityPolicy->InitFromOther(
    144        IntegrityPolicy::Cast(aOther->mIntegrityPolicy));
    145    mIntegrityPolicy = integrityPolicy;
    146  }
    147 }
    148 
    149 NS_IMETHODIMP PolicyContainer::InitFromCSP(nsIContentSecurityPolicy* aCSP) {
    150  SetCSP(aCSP);
    151 
    152  return NS_OK;
    153 }
    154 
    155 bool PolicyContainer::Equals(const PolicyContainer* aContainer,
    156                             const PolicyContainer* aOtherContainer) {
    157  // Do a quick pointer check first, also checks if both are null.
    158  if (aContainer == aOtherContainer) {
    159    return true;
    160  }
    161 
    162  // We checked if they were null above, so make sure one of them is not null.
    163  if (!aContainer || !aOtherContainer) {
    164    return false;
    165  }
    166 
    167  if (!nsCSPContext::Equals(aContainer->mCSP, aOtherContainer->mCSP)) {
    168    return false;
    169  }
    170 
    171  if (!IntegrityPolicy::Equals(
    172          IntegrityPolicy::Cast(aContainer->mIntegrityPolicy),
    173          IntegrityPolicy::Cast(aOtherContainer->mIntegrityPolicy))) {
    174    return false;
    175  }
    176 
    177  return true;
    178 }
    179 
    180 // == CSP ==
    181 void PolicyContainer::SetCSP(nsIContentSecurityPolicy* aPolicy) {
    182  mCSP = aPolicy;
    183 }
    184 
    185 nsIContentSecurityPolicy* PolicyContainer::GetCSP() const { return mCSP; }
    186 
    187 nsIContentSecurityPolicy* PolicyContainer::GetCSP(
    188    const nsIPolicyContainer* aPolicyContainer) {
    189  if (!aPolicyContainer) {
    190    return nullptr;
    191  }
    192  return PolicyContainer::Cast(aPolicyContainer)->GetCSP();
    193 }
    194 
    195 // == Integrity Policy ==
    196 void PolicyContainer::SetIntegrityPolicy(nsIIntegrityPolicy* aPolicy) {
    197  mIntegrityPolicy = aPolicy;
    198 }
    199 
    200 nsIIntegrityPolicy* PolicyContainer::GetIntegrityPolicy() const {
    201  return mIntegrityPolicy;
    202 }
    203 
    204 nsIIntegrityPolicy* PolicyContainer::GetIntegrityPolicy(
    205    const nsIPolicyContainer* aPolicyContainer) {
    206  if (!aPolicyContainer) {
    207    return nullptr;
    208  }
    209  return PolicyContainer::Cast(aPolicyContainer)->GetIntegrityPolicy();
    210 }
    211 
    212 NS_IMETHODIMP PolicyContainer::GetCsp(nsIContentSecurityPolicy** aCsp) {
    213  nsCOMPtr<nsIContentSecurityPolicy> csp = mCSP;
    214  csp.forget(aCsp);
    215  return NS_OK;
    216 }
    217 
    218 NS_IMPL_CLASSINFO(PolicyContainer, nullptr, 0, NS_IPOLICYCONTAINER_IID)
    219 NS_IMPL_ISUPPORTS_CI(PolicyContainer, nsIPolicyContainer, nsISerializable)