LCOV - code coverage report
Current view: top level - caps - BasePrincipal.h (source / functions) Hit Total Coverage
Test: output.info Lines: 28 45 62.2 %
Date: 2017-07-14 16:53:18 Functions: 11 14 78.6 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : #ifndef mozilla_BasePrincipal_h
       8             : #define mozilla_BasePrincipal_h
       9             : 
      10             : #include "nsJSPrincipals.h"
      11             : 
      12             : #include "mozilla/Attributes.h"
      13             : #include "mozilla/OriginAttributes.h"
      14             : 
      15             : class nsIContentSecurityPolicy;
      16             : class nsIObjectOutputStream;
      17             : class nsIObjectInputStream;
      18             : class nsIURI;
      19             : 
      20             : class ExpandedPrincipal;
      21             : 
      22             : namespace mozilla {
      23             : 
      24             : /*
      25             :  * Base class from which all nsIPrincipal implementations inherit. Use this for
      26             :  * default implementations and other commonalities between principal
      27             :  * implementations.
      28             :  *
      29             :  * We should merge nsJSPrincipals into this class at some point.
      30             :  */
      31             : class BasePrincipal : public nsJSPrincipals
      32             : {
      33             : public:
      34             :   enum PrincipalKind {
      35             :     eNullPrincipal,
      36             :     eCodebasePrincipal,
      37             :     eExpandedPrincipal,
      38             :     eSystemPrincipal
      39             :   };
      40             : 
      41             :   explicit BasePrincipal(PrincipalKind aKind);
      42             : 
      43             :   enum DocumentDomainConsideration { DontConsiderDocumentDomain, ConsiderDocumentDomain};
      44             :   bool Subsumes(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration);
      45             : 
      46             :   NS_IMETHOD GetOrigin(nsACString& aOrigin) final;
      47             :   NS_IMETHOD GetOriginNoSuffix(nsACString& aOrigin) final;
      48             :   NS_IMETHOD Equals(nsIPrincipal* other, bool* _retval) final;
      49             :   NS_IMETHOD EqualsConsideringDomain(nsIPrincipal* other, bool* _retval) final;
      50             :   NS_IMETHOD Subsumes(nsIPrincipal* other, bool* _retval) final;
      51             :   NS_IMETHOD SubsumesConsideringDomain(nsIPrincipal* other, bool* _retval) final;
      52             :   NS_IMETHOD SubsumesConsideringDomainIgnoringFPD(nsIPrincipal* other, bool* _retval) final;
      53             :   NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report, bool allowIfInheritsPrincipal) final;
      54             :   NS_IMETHOD GetCsp(nsIContentSecurityPolicy** aCsp) override;
      55             :   NS_IMETHOD SetCsp(nsIContentSecurityPolicy* aCsp) override;
      56             :   NS_IMETHOD EnsureCSP(nsIDOMDocument* aDocument, nsIContentSecurityPolicy** aCSP) override;
      57             :   NS_IMETHOD GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP) override;
      58             :   NS_IMETHOD EnsurePreloadCSP(nsIDOMDocument* aDocument, nsIContentSecurityPolicy** aCSP) override;
      59             :   NS_IMETHOD GetCspJSON(nsAString& outCSPinJSON) override;
      60             :   NS_IMETHOD GetIsNullPrincipal(bool* aResult) override;
      61             :   NS_IMETHOD GetIsCodebasePrincipal(bool* aResult) override;
      62             :   NS_IMETHOD GetIsExpandedPrincipal(bool* aResult) override;
      63             :   NS_IMETHOD GetIsSystemPrincipal(bool* aResult) override;
      64             :   NS_IMETHOD GetOriginAttributes(JSContext* aCx, JS::MutableHandle<JS::Value> aVal) final;
      65             :   NS_IMETHOD GetOriginSuffix(nsACString& aOriginSuffix) final;
      66             :   NS_IMETHOD GetAppId(uint32_t* aAppId) final;
      67             :   NS_IMETHOD GetIsInIsolatedMozBrowserElement(bool* aIsInIsolatedMozBrowserElement) final;
      68             :   NS_IMETHOD GetUserContextId(uint32_t* aUserContextId) final;
      69             :   NS_IMETHOD GetPrivateBrowsingId(uint32_t* aPrivateBrowsingId) final;
      70             : 
      71             :   virtual bool AddonHasPermission(const nsAString& aPerm);
      72             : 
      73           2 :   virtual bool IsCodebasePrincipal() const { return false; };
      74             : 
      75       76808 :   static BasePrincipal* Cast(nsIPrincipal* aPrin) { return static_cast<BasePrincipal*>(aPrin); }
      76             : 
      77             :   static already_AddRefed<BasePrincipal>
      78             :   CreateCodebasePrincipal(const nsACString& aOrigin);
      79             : 
      80             :   // These following method may not create a codebase principal in case it's
      81             :   // not possible to generate a correct origin from the passed URI. If this
      82             :   // happens, a NullPrincipal is returned.
      83             : 
      84             :   static already_AddRefed<BasePrincipal>
      85             :   CreateCodebasePrincipal(nsIURI* aURI, const OriginAttributes& aAttrs);
      86             : 
      87        1300 :   const OriginAttributes& OriginAttributesRef() final { return mOriginAttributes; }
      88          55 :   uint32_t AppId() const { return mOriginAttributes.mAppId; }
      89           0 :   uint32_t UserContextId() const { return mOriginAttributes.mUserContextId; }
      90           4 :   uint32_t PrivateBrowsingId() const { return mOriginAttributes.mPrivateBrowsingId; }
      91          23 :   bool IsInIsolatedMozBrowserElement() const { return mOriginAttributes.mInIsolatedMozBrowser; }
      92             : 
      93       98693 :   PrincipalKind Kind() const { return mKind; }
      94             : 
      95             :   already_AddRefed<BasePrincipal> CloneStrippingUserContextIdAndFirstPartyDomain();
      96             : 
      97             :   // Helper to check whether this principal is associated with an addon that
      98             :   // allows unprivileged code to load aURI.  aExplicit == true will prevent
      99             :   // use of all_urls permission, requiring the domain in its permissions.
     100             :   bool AddonAllowsLoad(nsIURI* aURI, bool aExplicit = false);
     101             : 
     102             :   // Call these to avoid the cost of virtual dispatch.
     103             :   inline bool FastEquals(nsIPrincipal* aOther);
     104             :   inline bool FastEqualsConsideringDomain(nsIPrincipal* aOther);
     105             :   inline bool FastSubsumes(nsIPrincipal* aOther);
     106             :   inline bool FastSubsumesConsideringDomain(nsIPrincipal* aOther);
     107             :   inline bool FastSubsumesConsideringDomainIgnoringFPD(nsIPrincipal* aOther);
     108             : 
     109             : protected:
     110             :   virtual ~BasePrincipal();
     111             : 
     112             :   // Note that this does not check OriginAttributes. Callers that depend on
     113             :   // those must call Subsumes instead.
     114             :   virtual bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsider) = 0;
     115             : 
     116             :   // Internal, side-effect-free check to determine whether the concrete
     117             :   // principal would allow the load ignoring any common behavior implemented in
     118             :   // BasePrincipal::CheckMayLoad.
     119             :   virtual bool MayLoadInternal(nsIURI* aURI) = 0;
     120             :   friend class ::ExpandedPrincipal;
     121             : 
     122             :   void
     123           1 :   SetHasExplicitDomain()
     124             :   {
     125           1 :     mHasExplicitDomain = true;
     126           1 :   }
     127             : 
     128             :   // This function should be called as the last step of the initialization of the
     129             :   // principal objects.  It's typically called as the last step from the Init()
     130             :   // method of the child classes.
     131             :   void FinishInit(const nsACString& aOriginNoSuffix,
     132             :                   const OriginAttributes& aOriginAttributes);
     133             : 
     134             :   nsCOMPtr<nsIContentSecurityPolicy> mCSP;
     135             :   nsCOMPtr<nsIContentSecurityPolicy> mPreloadCSP;
     136             : 
     137             : private:
     138             :   static already_AddRefed<BasePrincipal>
     139             :   CreateCodebasePrincipal(nsIURI* aURI, const OriginAttributes& aAttrs,
     140             :                           const nsACString& aOriginNoSuffix);
     141             : 
     142             :   nsCOMPtr<nsIAtom> mOriginNoSuffix;
     143             :   nsCOMPtr<nsIAtom> mOriginSuffix;
     144             : 
     145             :   OriginAttributes mOriginAttributes;
     146             :   PrincipalKind mKind;
     147             :   bool mHasExplicitDomain;
     148             :   bool mInitialized;
     149             : };
     150             : 
     151             : inline bool
     152       19459 : BasePrincipal::FastEquals(nsIPrincipal* aOther)
     153             : {
     154       19459 :   auto other = Cast(aOther);
     155       19459 :   if (Kind() != other->Kind()) {
     156             :     // Principals of different kinds can't be equal.
     157        2517 :     return false;
     158             :   }
     159             : 
     160             :   // Two principals are considered to be equal if their origins are the same.
     161             :   // If the two principals are codebase principals, their origin attributes
     162             :   // (aka the origin suffix) must also match.
     163             :   // If the two principals are null principals, they're only equal if they're
     164             :   // the same object.
     165       16942 :   if (Kind() == eNullPrincipal || Kind() == eSystemPrincipal) {
     166       16881 :     return this == other;
     167             :   }
     168             : 
     169          61 :   if (Kind() == eCodebasePrincipal) {
     170         122 :     return mOriginNoSuffix == other->mOriginNoSuffix &&
     171         122 :            mOriginSuffix == other->mOriginSuffix;
     172             :   }
     173             : 
     174           0 :   MOZ_ASSERT(Kind() == eExpandedPrincipal);
     175           0 :   return mOriginNoSuffix == other->mOriginNoSuffix;
     176             : }
     177             : 
     178             : inline bool
     179           0 : BasePrincipal::FastEqualsConsideringDomain(nsIPrincipal* aOther)
     180             : {
     181             :   // If neither of the principals have document.domain set, we use the fast path
     182             :   // in Equals().  Otherwise, we fall back to the slow path below.
     183           0 :   auto other = Cast(aOther);
     184           0 :   if (!mHasExplicitDomain && !other->mHasExplicitDomain) {
     185           0 :     return FastEquals(aOther);
     186             :   }
     187             : 
     188           0 :   return Subsumes(aOther, ConsiderDocumentDomain) &&
     189           0 :          other->Subsumes(this, ConsiderDocumentDomain);
     190             : }
     191             : 
     192             : inline bool
     193       19374 : BasePrincipal::FastSubsumes(nsIPrincipal* aOther)
     194             : {
     195             :   // If two principals are equal, then they both subsume each other.
     196             :   // We deal with two special cases first:
     197             :   // Null principals only subsume each other if they are equal, and are only
     198             :   // equal if they're the same object.
     199       19374 :   auto other = Cast(aOther);
     200       19374 :   if (Kind() == eNullPrincipal && other->Kind() == eNullPrincipal) {
     201           0 :     return this == other;
     202             :   }
     203       19374 :   if (FastEquals(aOther)) {
     204       16861 :     return true;
     205             :   }
     206             : 
     207             :   // Otherwise, fall back to the slow path.
     208        2513 :   return Subsumes(aOther, DontConsiderDocumentDomain);
     209             : }
     210             : 
     211             : inline bool
     212       19257 : BasePrincipal::FastSubsumesConsideringDomain(nsIPrincipal* aOther)
     213             : {
     214             :   // If neither of the principals have document.domain set, we hand off to
     215             :   // FastSubsumes() which has fast paths for some special cases. Otherwise, we fall
     216             :   // back to the slow path below.
     217       19257 :   if (!mHasExplicitDomain && !Cast(aOther)->mHasExplicitDomain) {
     218       19257 :     return FastSubsumes(aOther);
     219             :   }
     220             : 
     221           0 :   return Subsumes(aOther, ConsiderDocumentDomain);
     222             : }
     223             : 
     224             : inline bool
     225           0 : BasePrincipal::FastSubsumesConsideringDomainIgnoringFPD(nsIPrincipal* aOther)
     226             : {
     227           0 :   if (Kind() == eCodebasePrincipal &&
     228           0 :       !dom::ChromeUtils::IsOriginAttributesEqualIgnoringFPD(
     229           0 :             mOriginAttributes, Cast(aOther)->mOriginAttributes)) {
     230           0 :     return false;
     231             :   }
     232             : 
     233           0 :  return SubsumesInternal(aOther, ConsiderDocumentDomain);
     234             : }
     235             : 
     236             : } // namespace mozilla
     237             : 
     238             : #endif /* mozilla_BasePrincipal_h */

Generated by: LCOV version 1.13