tor-browser

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

PermissionManager.h (29661B)


      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_PermissionManager_h
      8 #define mozilla_PermissionManager_h
      9 
     10 #include "nsIPermissionManager.h"
     11 #include "nsIAsyncShutdown.h"
     12 #include "nsIObserver.h"
     13 #include "nsIRemotePermissionService.h"
     14 #include "nsWeakReference.h"
     15 #include "nsCOMPtr.h"
     16 #include "nsIURI.h"
     17 #include "nsTHashtable.h"
     18 #include "nsTArray.h"
     19 #include "nsString.h"
     20 #include "nsHashKeys.h"
     21 #include "nsRefPtrHashtable.h"
     22 #include "mozilla/Atomics.h"
     23 #include "mozilla/Monitor.h"
     24 #include "mozilla/MozPromise.h"
     25 #include "mozilla/OriginAttributes.h"
     26 #include "mozilla/StaticMutex.h"
     27 #include "mozilla/ThreadBound.h"
     28 #include "mozilla/Variant.h"
     29 #include "mozilla/Vector.h"
     30 
     31 #include <utility>
     32 
     33 class mozIStorageConnection;
     34 class mozIStorageStatement;
     35 class nsIInputStream;
     36 class nsIPermission;
     37 class nsIPrefBranch;
     38 
     39 namespace IPC {
     40 struct Permission;
     41 }
     42 
     43 namespace mozilla {
     44 class OriginAttributesPattern;
     45 
     46 namespace dom {
     47 class ContentChild;
     48 }  // namespace dom
     49 
     50 ////////////////////////////////////////////////////////////////////////////////
     51 
     52 class PermissionManager final : public nsIPermissionManager,
     53                                public nsIObserver,
     54                                public nsSupportsWeakReference,
     55                                public nsIAsyncShutdownBlocker {
     56 public:
     57  class PermissionEntry {
     58   public:
     59    PermissionEntry(int64_t aID, uint32_t aType, uint32_t aPermission,
     60                    uint32_t aExpireType, int64_t aExpireTime,
     61                    int64_t aModificationTime)
     62        : mID(aID),
     63          mExpireTime(aExpireTime),
     64          mModificationTime(aModificationTime),
     65          mType(aType),
     66          mPermission(aPermission),
     67          mExpireType(aExpireType),
     68          mNonSessionPermission(aPermission),
     69          mNonSessionExpireType(aExpireType),
     70          mNonSessionExpireTime(aExpireTime) {}
     71 
     72    int64_t mID;
     73    int64_t mExpireTime;
     74    int64_t mModificationTime;
     75    uint32_t mType;
     76    uint32_t mPermission;
     77    uint32_t mExpireType;
     78    uint32_t mNonSessionPermission;
     79    uint32_t mNonSessionExpireType;
     80    uint32_t mNonSessionExpireTime;
     81  };
     82 
     83  /**
     84   * PermissionKey is the key used by PermissionHashKey hash table.
     85   */
     86  class PermissionKey {
     87   public:
     88    static PermissionKey* CreateFromPrincipal(nsIPrincipal* aPrincipal,
     89                                              bool aForceStripOA,
     90                                              bool aScopeToSite,
     91                                              nsresult& aResult);
     92    static PermissionKey* CreateFromURI(nsIURI* aURI, nsresult& aResult);
     93    static PermissionKey* CreateFromURIAndOriginAttributes(
     94        nsIURI* aURI, const OriginAttributes* aOriginAttributes,
     95        bool aForceStripOA, nsresult& aResult);
     96 
     97    explicit PermissionKey(const nsACString& aOrigin)
     98        : mOrigin(aOrigin), mHashCode(HashString(aOrigin)) {}
     99 
    100    bool operator==(const PermissionKey& aKey) const {
    101      return mOrigin.Equals(aKey.mOrigin);
    102    }
    103 
    104    PLDHashNumber GetHashCode() const { return mHashCode; }
    105 
    106    NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PermissionKey)
    107 
    108    const nsCString mOrigin;
    109    const PLDHashNumber mHashCode;
    110 
    111   private:
    112    // Default ctor shouldn't be used.
    113    PermissionKey() = delete;
    114 
    115    // Dtor shouldn't be used outside of the class.
    116    ~PermissionKey() {};
    117  };
    118 
    119  class PermissionHashKey : public nsRefPtrHashKey<PermissionKey> {
    120   public:
    121    explicit PermissionHashKey(const PermissionKey* aPermissionKey)
    122        : nsRefPtrHashKey<PermissionKey>(aPermissionKey) {}
    123 
    124    PermissionHashKey(PermissionHashKey&& toCopy)
    125        : nsRefPtrHashKey<PermissionKey>(std::move(toCopy)),
    126          mPermissions(std::move(toCopy.mPermissions)) {}
    127 
    128    bool KeyEquals(const PermissionKey* aKey) const {
    129      return *aKey == *GetKey();
    130    }
    131 
    132    static PLDHashNumber HashKey(const PermissionKey* aKey) {
    133      return aKey->GetHashCode();
    134    }
    135 
    136    // Force the hashtable to use the copy constructor when shuffling entries
    137    // around, otherwise the Auto part of our AutoTArray won't be happy!
    138    enum { ALLOW_MEMMOVE = false };
    139 
    140    inline nsTArray<PermissionEntry>& GetPermissions() { return mPermissions; }
    141    inline const nsTArray<PermissionEntry>& GetPermissions() const {
    142      return mPermissions;
    143    }
    144 
    145    inline int32_t GetPermissionIndex(uint32_t aType) const {
    146      for (uint32_t i = 0; i < mPermissions.Length(); ++i) {
    147        if (mPermissions[i].mType == aType) {
    148          return i;
    149        }
    150      }
    151 
    152      return -1;
    153    }
    154 
    155    inline PermissionEntry GetPermission(uint32_t aType) const {
    156      for (uint32_t i = 0; i < mPermissions.Length(); ++i) {
    157        if (mPermissions[i].mType == aType) {
    158          return mPermissions[i];
    159        }
    160      }
    161 
    162      // unknown permission... return relevant data
    163      return PermissionEntry(-1, aType, nsIPermissionManager::UNKNOWN_ACTION,
    164                             nsIPermissionManager::EXPIRE_NEVER, 0, 0);
    165    }
    166 
    167   private:
    168    AutoTArray<PermissionEntry, 1> mPermissions;
    169  };
    170 
    171  // nsISupports
    172  NS_DECL_THREADSAFE_ISUPPORTS
    173  NS_DECL_NSIPERMISSIONMANAGER
    174  NS_DECL_NSIOBSERVER
    175  NS_DECL_NSIASYNCSHUTDOWNBLOCKER
    176 
    177  PermissionManager();
    178  static already_AddRefed<nsIPermissionManager> GetXPCOMSingleton();
    179  static already_AddRefed<PermissionManager> GetInstance();
    180 
    181  // enums for AddInternal()
    182  enum OperationType {
    183    eOperationNone,
    184    eOperationAdding,
    185    eOperationRemoving,
    186    eOperationChanging,
    187    eOperationReplacingDefault
    188  };
    189 
    190  enum DBOperationType { eNoDBOperation, eWriteToDB };
    191 
    192  enum NotifyOperationType { eDontNotify, eNotify };
    193 
    194  // Similar to TestPermissionFromPrincipal, except that it is used only for
    195  // permissions which can never have default values.
    196  nsresult TestPermissionWithoutDefaultsFromPrincipal(nsIPrincipal* aPrincipal,
    197                                                      const nsACString& aType,
    198                                                      uint32_t* aPermission);
    199 
    200  nsresult RemovePermissionsWithAttributes(
    201      OriginAttributesPattern& aPattern,
    202      const nsTArray<nsCString>& aTypeInclusions = {},
    203      const nsTArray<nsCString>& aTypeExceptions = {}) MOZ_REQUIRES(mMonitor);
    204 
    205  /**
    206   * See `nsIPermissionManager::GetPermissionsWithKey` for more info on
    207   * permission keys.
    208   *
    209   * Get the permission key corresponding to the given Principal. This method is
    210   * intentionally infallible, as we want to provide an permission key to every
    211   * principal. Principals which don't have meaningful URIs with http://,
    212   * https://, or ftp:// schemes are given the default "" Permission Key.
    213   *
    214   * @param aPrincipal  The Principal which the key is to be extracted from.
    215   * @param aForceStripOA Whether to force stripping the principals origin
    216   *        attributes prior to generating the key.
    217   * @param aSiteScopePermissions  Whether to prepare the key for permissions
    218   *        scoped to the Principal's site, rather than origin. These are looked
    219   *        up independently. Scoping of a permission is fully determined by its
    220   *        type and determined by calls to the function IsSiteScopedPermission.
    221   * @param aKey  A string which will be filled with the permission
    222   * key.
    223   */
    224  static nsresult GetKeyForPrincipal(nsIPrincipal* aPrincipal,
    225                                     bool aForceStripOA,
    226                                     bool aSiteScopePermissions,
    227                                     nsACString& aKey);
    228 
    229  /**
    230   * See `nsIPermissionManager::GetPermissionsWithKey` for more info on
    231   * permission keys.
    232   *
    233   * Get the permission key corresponding to the given Origin. This method is
    234   * like GetKeyForPrincipal, except that it avoids creating a nsIPrincipal
    235   * object when you already have access to an origin string.
    236   *
    237   * If this method is passed a nonsensical origin string it may produce a
    238   * nonsensical permission key result.
    239   *
    240   * @param aOrigin  The origin which the key is to be extracted from.
    241   * @param aForceStripOA Whether to force stripping the origins attributes
    242   *        prior to generating the key.
    243   * @param aSiteScopePermissions  Whether to prepare the key for permissions
    244   *        scoped to the Principal's site, rather than origin. These are looked
    245   *        up independently. Scoping of a permission is fully determined by its
    246   *        type and determined by calls to the function IsSiteScopedPermission.
    247   * @param aKey  A string which will be filled with the permission
    248   * key.
    249   */
    250  static nsresult GetKeyForOrigin(const nsACString& aOrigin, bool aForceStripOA,
    251                                  bool aSiteScopePermissions, nsACString& aKey);
    252 
    253  /**
    254   * See `nsIPermissionManager::GetPermissionsWithKey` for more info on
    255   * permission keys.
    256   *
    257   * Get the permission key corresponding to the given Principal and type. This
    258   * method is intentionally infallible, as we want to provide an permission key
    259   * to every principal. Principals which don't have meaningful URIs with
    260   * http://, https://, or ftp:// schemes are given the default "" Permission
    261   * Key.
    262   *
    263   * This method is different from GetKeyForPrincipal in that it also takes
    264   * permissions which must be sent down before loading a document into account.
    265   *
    266   * @param aPrincipal  The Principal which the key is to be extracted from.
    267   * @param aType  The type of the permission to get the key for.
    268   * @param aPermissionKey  A string which will be filled with the permission
    269   * key.
    270   */
    271  static nsresult GetKeyForPermission(nsIPrincipal* aPrincipal,
    272                                      const nsACString& aType,
    273                                      nsACString& aKey);
    274 
    275  /**
    276   * See `nsIPermissionManager::GetPermissionsWithKey` for more info on
    277   * permission keys.
    278   *
    279   * Get all permissions keys which could correspond to the given principal.
    280   * This method, like GetKeyForPrincipal, is infallible and should always
    281   * produce at least one (key, origin) pair.
    282   *
    283   * Unlike GetKeyForPrincipal, this method also gets the keys for base domains
    284   * of the given principal. All keys returned by this method must be available
    285   * in the content process for a given URL to successfully have its permissions
    286   * checked in the `aExactHostMatch = false` situation.
    287   *
    288   * @param aPrincipal  The Principal which the key is to be extracted from.
    289   * @return returns an array of (key, origin) pairs.
    290   */
    291  static nsTArray<std::pair<nsCString, nsCString>> GetAllKeysForPrincipal(
    292      nsIPrincipal* aPrincipal);
    293 
    294  // From ContentChild.
    295  nsresult RemoveAllFromIPC();
    296 
    297  /**
    298   * Returns false if this permission manager wouldn't have the permission
    299   * requested available.
    300   *
    301   * If aType is empty, checks that the permission manager would have all
    302   * permissions available for the given principal.
    303   */
    304  bool PermissionAvailable(nsIPrincipal* aPrincipal, const nsACString& aType);
    305 
    306  /**
    307   * The content process doesn't have access to every permission. Instead, when
    308   * LOAD_DOCUMENT_URI channels for http://, https://, and ftp:// URIs are
    309   * opened, the permissions for those channels are sent down to the content
    310   * process before the OnStartRequest message. Permissions for principals with
    311   * other schemes are sent down at process startup.
    312   *
    313   * Permissions are keyed and grouped by "Permission Key"s.
    314   * `PermissionManager::GetKeyForPrincipal` provides the mechanism for
    315   * determining the permission key for a given principal.
    316   *
    317   * This method may only be called in the parent process. It fills the nsTArray
    318   * argument with the IPC::Permission objects which have a matching origin.
    319   *
    320   * @param origin The origin to use to find the permissions of interest.
    321   * @param key The key to use to find the permissions of interest. Only used
    322   *            when the origin argument is empty.
    323   * @param perms  An array which will be filled with the permissions which
    324   *               match the given origin.
    325   */
    326  bool GetPermissionsFromOriginOrKey(const nsACString& aOrigin,
    327                                     const nsACString& aKey,
    328                                     nsTArray<IPC::Permission>& aPerms);
    329 
    330  /**
    331   * See `PermissionManager::GetPermissionsWithKey` for more info on
    332   * Permission keys.
    333   *
    334   * `SetPermissionsWithKey` may only be called in the Child process, and
    335   * initializes the permission manager with the permissions for a given
    336   * Permission key. marking permissions with that key as available.
    337   *
    338   * @param permissionKey  The key for the permissions which have been sent
    339   * over.
    340   * @param perms  An array with the permissions which match the given key.
    341   */
    342  void SetPermissionsWithKey(const nsACString& aPermissionKey,
    343                             nsTArray<IPC::Permission>& aPerms);
    344 
    345  /**
    346   * Add a callback which should be run when all permissions are available for
    347   * the given nsIPrincipal. This method invokes the callback runnable
    348   * synchronously when the permissions are already available. Otherwise the
    349   * callback will be run asynchronously in SystemGroup when all permissions
    350   * are available in the future.
    351   *
    352   * NOTE: This method will not request the permissions be sent by the parent
    353   * process. This should only be used to wait for permissions which may not
    354   * have arrived yet in order to ensure they are present.
    355   *
    356   * @param aPrincipal The principal to wait for permissions to be available
    357   * for.
    358   * @param aRunnable  The runnable to run when permissions are available for
    359   * the given principal.
    360   */
    361  void WhenPermissionsAvailable(nsIPrincipal* aPrincipal,
    362                                nsIRunnable* aRunnable);
    363 
    364  /**
    365   * Strip origin attributes for permissions, depending on permission isolation
    366   * pref state.
    367   * @param aForceStrip If true, strips user context and private browsing id,
    368   * ignoring permission isolation prefs.
    369   * @param aOriginAttributes object to strip.
    370   */
    371  static void MaybeStripOriginAttributes(bool aForceStrip,
    372                                         OriginAttributes& aOriginAttributes);
    373 
    374  nsresult Add(nsIPrincipal* aPrincipal, const nsACString& aType,
    375               uint32_t aPermission, int64_t aID, uint32_t aExpireType,
    376               int64_t aExpireTime, int64_t aModificationTime,
    377               NotifyOperationType aNotifyOperation,
    378               DBOperationType aDBOperation,
    379               const nsACString* aOriginString = nullptr,
    380               const bool aAllowPersistInPrivateBrowsing = false);
    381 
    382 private:
    383  ~PermissionManager();
    384  nsresult Init();
    385 
    386  static StaticMutex sCreationMutex;
    387  // Holding our singleton instance until shutdown.
    388  static StaticRefPtr<PermissionManager> sInstanceHolder
    389      MOZ_GUARDED_BY(sCreationMutex);
    390  // Flag that signals shutdown has started.
    391  static bool sInstanceDead MOZ_GUARDED_BY(sCreationMutex);
    392 
    393  /**
    394   * Get all permissions for a given principal, which should not be isolated
    395   * by user context or private browsing. The principal has its origin
    396   * attributes stripped before perm db lookup. This is currently only affects
    397   * the "cookie" permission.
    398   * @param aPrincipal Used for creating the permission key.
    399   * @param aSiteScopePermissions Used to specify whether to get strip perms for
    400   * site scoped permissions (defined in IsSiteScopedPermission) or all other
    401   * permissions. Also used to create the permission key.
    402   */
    403  nsresult GetStripPermsForPrincipal(nsIPrincipal* aPrincipal,
    404                                     bool aSiteScopePermissions,
    405                                     nsTArray<PermissionEntry>& aResult)
    406      MOZ_REQUIRES(mMonitor);
    407 
    408  // Returns -1 on failure
    409  int32_t GetTypeIndex(const nsACString& aType, bool aAdd = false)
    410      MOZ_REQUIRES(mMonitor);
    411 
    412  // Returns whether the given combination of expire type and expire time are
    413  // expired. Note that EXPIRE_SESSION only honors expireTime if it is nonzero.
    414  bool HasExpired(uint32_t aExpireType, int64_t aExpireTime);
    415 
    416  // Appends the permissions associated with this principal to aResult.
    417  // If the onlySiteScopePermissions argument is true, the permissions searched
    418  // are those for the site of the principal and only the permissions that are
    419  // site-scoped are used.
    420  nsresult GetAllForPrincipalHelper(nsIPrincipal* aPrincipal,
    421                                    bool aSiteScopePermissions,
    422                                    nsTArray<RefPtr<nsIPermission>>& aResult)
    423      MOZ_REQUIRES(mMonitor);
    424 
    425  // Returns true if the principal can be used for getting / setting
    426  // permissions. If the principal can not be used an error code may be
    427  // returned.
    428  nsresult ShouldHandlePrincipalForPermission(
    429      nsIPrincipal* aPrincipal, bool& aIsPermissionPrincipalValid);
    430 
    431  // Returns PermissionHashKey for a given { host, isInBrowserElement } tuple.
    432  // This is not simply using PermissionKey because we will walk-up domains in
    433  // case of |host| contains sub-domains. Returns null if nothing found. Also
    434  // accepts host on the format "<foo>". This will perform an exact match lookup
    435  // as the string doesn't contain any dots.
    436  PermissionHashKey* GetPermissionHashKey(nsIPrincipal* aPrincipal,
    437                                          uint32_t aType, bool aExactHostMatch)
    438      MOZ_REQUIRES(mMonitor);
    439 
    440  nsresult RemoveFromPrincipalInternal(nsIPrincipal* aPrincipal,
    441                                       const nsACString& aType)
    442      MOZ_REQUIRES(mMonitor);
    443 
    444  // Returns PermissionHashKey for a given { host, isInBrowserElement } tuple.
    445  // This is not simply using PermissionKey because we will walk-up domains in
    446  // case of |host| contains sub-domains. Returns null if nothing found. Also
    447  // accepts host on the format "<foo>". This will perform an exact match lookup
    448  // as the string doesn't contain any dots.
    449  PermissionHashKey* GetPermissionHashKey(
    450      nsIURI* aURI, const OriginAttributes* aOriginAttributes, uint32_t aType,
    451      bool aExactHostMatch) MOZ_REQUIRES(mMonitor);
    452 
    453  // to be used by internal caller as a helper method; monitor lock must be
    454  // held.
    455  bool PermissionAvailableInternal(nsIPrincipal* aPrincipal,
    456                                   const nsACString& aType)
    457      MOZ_REQUIRES(mMonitor);
    458 
    459  // The int32_t is the type index, the nsresult is an early bail-out return
    460  // code.
    461  typedef Variant<int32_t, nsresult> TestPreparationResult;
    462  TestPreparationResult CommonPrepareToTestPermission(
    463      nsIPrincipal* aPrincipal, int32_t aTypeIndex, const nsACString& aType,
    464      uint32_t* aPermission, uint32_t aDefaultPermission,
    465      bool aDefaultPermissionIsValid, bool aExactHostMatch,
    466      bool aIncludingSession) MOZ_REQUIRES(mMonitor);
    467 
    468  // If aTypeIndex is passed -1, we try to inder the type index from aType.
    469  nsresult CommonTestPermission(nsIPrincipal* aPrincipal, int32_t aTypeIndex,
    470                                const nsACString& aType, uint32_t* aPermission,
    471                                uint32_t aDefaultPermission,
    472                                bool aDefaultPermissionIsValid,
    473                                bool aExactHostMatch, bool aIncludingSession)
    474      MOZ_REQUIRES(mMonitor);
    475 
    476  // If aTypeIndex is passed -1, we try to inder the type index from aType.
    477  nsresult CommonTestPermission(nsIURI* aURI, int32_t aTypeIndex,
    478                                const nsACString& aType, uint32_t* aPermission,
    479                                uint32_t aDefaultPermission,
    480                                bool aDefaultPermissionIsValid,
    481                                bool aExactHostMatch, bool aIncludingSession)
    482      MOZ_REQUIRES(mMonitor);
    483 
    484  nsresult CommonTestPermission(
    485      nsIURI* aURI, const OriginAttributes* aOriginAttributes,
    486      int32_t aTypeIndex, const nsACString& aType, uint32_t* aPermission,
    487      uint32_t aDefaultPermission, bool aDefaultPermissionIsValid,
    488      bool aExactHostMatch, bool aIncludingSession) MOZ_REQUIRES(mMonitor);
    489 
    490  // Only one of aPrincipal or aURI is allowed to be passed in.
    491  nsresult CommonTestPermissionInternal(
    492      nsIPrincipal* aPrincipal, nsIURI* aURI,
    493      const OriginAttributes* aOriginAttributes, int32_t aTypeIndex,
    494      const nsACString& aType, uint32_t* aPermission, bool aExactHostMatch,
    495      bool aIncludingSession) MOZ_REQUIRES(mMonitor);
    496 
    497  nsresult OpenDatabase(nsIFile* permissionsFile);
    498 
    499  void InitDB(bool aRemoveFile) MOZ_REQUIRES(mMonitor);
    500  nsresult TryInitDB(bool aRemoveFile, nsIInputStream* aDefaultsInputStream,
    501                     const MonitorAutoLock& aProofOfLock)
    502      MOZ_REQUIRES(mMonitor);
    503 
    504  void AddIdleDailyMaintenanceJob();
    505  void RemoveIdleDailyMaintenanceJob();
    506  void PerformIdleDailyMaintenance() MOZ_REQUIRES(mMonitor);
    507 
    508  nsresult ImportLatestDefaults() MOZ_REQUIRES(mMonitor);
    509  already_AddRefed<nsIInputStream> GetDefaultsInputStream();
    510  void ConsumeDefaultsInputStream(nsIInputStream* aInputStream,
    511                                  const MonitorAutoLock& aProofOfLock)
    512      MOZ_REQUIRES(mMonitor);
    513 
    514  nsresult CreateTable();
    515  void NotifyObserversWithPermission(
    516      nsIPrincipal* aPrincipal, const nsACString& aType, uint32_t aPermission,
    517      uint32_t aExpireType, int64_t aExpireTime, int64_t aModificationTime,
    518      const nsString& aData) MOZ_REQUIRES(mMonitor);
    519 
    520  void NotifyObservers(const nsCOMPtr<nsIPermission>& aPermission,
    521                       const nsString& aData) MOZ_REQUIRES(mMonitor);
    522 
    523  // Finalize all statements, close the DB and null it.
    524  enum CloseDBNextOp {
    525    eNone,
    526    eRebuldOnSuccess,
    527    eShutdown,
    528  };
    529  void CloseDB(CloseDBNextOp aNextOp) MOZ_REQUIRES(mMonitor);
    530 
    531  nsresult RemoveAllInternal(bool aNotifyObservers) MOZ_REQUIRES(mMonitor);
    532  nsresult RemoveAllFromMemory() MOZ_REQUIRES(mMonitor);
    533 
    534  void UpdateDB(OperationType aOp, int64_t aID, const nsACString& aOrigin,
    535                const nsACString& aType, uint32_t aPermission,
    536                uint32_t aExpireType, int64_t aExpireTime,
    537                int64_t aModificationTime) MOZ_REQUIRES(mMonitor);
    538 
    539  /**
    540   * This method removes all permissions modified after the specified time.
    541   */
    542  nsresult RemoveAllModifiedSince(int64_t aModificationTime)
    543      MOZ_REQUIRES(mMonitor);
    544 
    545  // Removes all permissions with a private browsing principal (i.e.
    546  // privateBrowsingId OA != 0).
    547  nsresult RemoveAllForPrivateBrowsing() MOZ_REQUIRES(mMonitor);
    548 
    549  // Helper function which removes all permissions for which aCondition
    550  // evaluates to true.
    551  nsresult RemovePermissionEntries(
    552      const std::function<bool(const PermissionEntry& aPermEntry,
    553                               const nsCOMPtr<nsIPrincipal>& aPrincipal)>&
    554          aCondition,
    555      bool aComputePrincipalForCondition = true) MOZ_REQUIRES(mMonitor);
    556 
    557  // Overload of RemovePermissionEntries allowing aCondition not to take
    558  // aPrincipal as an argument.
    559  nsresult RemovePermissionEntries(
    560      const std::function<bool(const PermissionEntry& aPermEntry)>& aCondition)
    561      MOZ_REQUIRES(mMonitor);
    562 
    563  // Helper function which returns all permissions for which aCondition
    564  // evaluates to true.
    565  nsresult GetPermissionEntries(
    566      const std::function<bool(const PermissionEntry& aPermEntry)>& aCondition,
    567      nsTArray<RefPtr<nsIPermission>>& aResult) MOZ_REQUIRES(mMonitor);
    568 
    569  // This method must be called before doing any operation to be sure that the
    570  // DB reading has been completed. This method is also in charge to complete
    571  // the migrations if needed.
    572  void EnsureReadCompleted() MOZ_REQUIRES(mMonitor);
    573 
    574  nsresult AddInternal(nsIPrincipal* aPrincipal, const nsACString& aType,
    575                       uint32_t aPermission, int64_t aID, uint32_t aExpireType,
    576                       int64_t aExpireTime, int64_t aModificationTime,
    577                       NotifyOperationType aNotifyOperation,
    578                       DBOperationType aDBOperation,
    579                       const nsACString* aOriginString = nullptr,
    580                       const bool aAllowPersistInPrivateBrowsing = false)
    581      MOZ_REQUIRES(mMonitor);
    582 
    583  void MaybeAddReadEntryFromMigration(const nsACString& aOrigin,
    584                                      const nsCString& aType,
    585                                      uint32_t aPermission,
    586                                      uint32_t aExpireType, int64_t aExpireTime,
    587                                      int64_t aModificationTime, int64_t aId)
    588      MOZ_REQUIRES(mMonitor);
    589 
    590  nsCOMPtr<nsIAsyncShutdownClient> GetAsyncShutdownBarrier() const;
    591 
    592  void FinishAsyncShutdown();
    593 
    594  nsRefPtrHashtable<nsCStringHashKey, GenericNonExclusivePromise::Private>
    595      mPermissionKeyPromiseMap MOZ_GUARDED_BY(mMonitor);
    596 
    597  nsCOMPtr<nsIFile> mPermissionsFile MOZ_GUARDED_BY(mMonitor);
    598 
    599  // This monitor is used to ensure the database reading before any other
    600  // operation. The reading of the database happens OMT. See |State| to know the
    601  // steps of the database reading.
    602  Monitor mMonitor MOZ_UNANNOTATED;
    603 
    604  enum State {
    605    // Initial state. The database has not been read yet.
    606    // |TryInitDB| is called at startup time to read the database OMT.
    607    // During the reading, |mReadEntries| will be populated with all the
    608    // existing permissions.
    609    eInitializing,
    610 
    611    // At the end of the database reading, we are in this state. A runnable is
    612    // executed to call |EnsureReadCompleted| on the main thread.
    613    // |EnsureReadCompleted| processes |mReadEntries| and goes to the next
    614    // state.
    615    eDBInitialized,
    616 
    617    // The permissions are fully read and any pending operation can proceed.
    618    eReady,
    619 
    620    // The permission manager has been terminated. No extra database operations
    621    // will be allowed.
    622    eClosed,
    623  };
    624  Atomic<State> mState;
    625 
    626  // A single entry, from the database.
    627  struct ReadEntry {
    628    ReadEntry()
    629        : mId(0),
    630          mPermission(0),
    631          mExpireType(0),
    632          mExpireTime(0),
    633          mModificationTime(0),
    634          mFromMigration(false) {}
    635 
    636    nsCString mOrigin;
    637    nsCString mType;
    638    int64_t mId;
    639    uint32_t mPermission;
    640    uint32_t mExpireType;
    641    int64_t mExpireTime;
    642    int64_t mModificationTime;
    643 
    644    // true if this entry is the result of a migration.
    645    bool mFromMigration;
    646  };
    647 
    648  // List of entries read from the database. It will be populated OMT and
    649  // consumed on the main-thread.
    650  // This array is protected by the monitor.
    651  nsTArray<ReadEntry> mReadEntries MOZ_GUARDED_BY(mMonitor);
    652 
    653  // A single entry, from the database.
    654  struct MigrationEntry {
    655    MigrationEntry()
    656        : mId(0),
    657          mPermission(0),
    658          mExpireType(0),
    659          mExpireTime(0),
    660          mModificationTime(0) {}
    661 
    662    nsCString mHost;
    663    nsCString mType;
    664    int64_t mId;
    665    uint32_t mPermission;
    666    uint32_t mExpireType;
    667    int64_t mExpireTime;
    668    int64_t mModificationTime;
    669  };
    670 
    671  // List of entries read from the database. It will be populated OMT and
    672  // consumed on the main-thread. The migration entries will be converted to
    673  // ReadEntry in |CompleteMigrations|.
    674  // This array is protected by the monitor.
    675  nsTArray<MigrationEntry> mMigrationEntries MOZ_GUARDED_BY(mMonitor);
    676 
    677  // A single entry from the defaults URL.
    678  struct DefaultEntry {
    679    nsCString mOrigin;
    680    nsCString mType;
    681    uint32_t mPermission = 0;
    682  };
    683 
    684  // List of entries read from the default settings.
    685  // This array is protected by the monitor.
    686  nsTArray<DefaultEntry> mDefaultEntriesForImport MOZ_GUARDED_BY(mMonitor);
    687  // Adds a default permission entry to AddDefaultEntryForImport for given
    688  // origin, type and value
    689  void AddDefaultEntryForImport(const nsACString& aOrigin,
    690                                const nsCString& aType, uint32_t aPermission,
    691                                const MonitorAutoLock& aProofOfLock)
    692      MOZ_REQUIRES(mMonitor);
    693  // Given a default entry, import it as a default permission (id = -1) into the
    694  // permission manager without storing it to disk. If permission isolation for
    695  // private browsing is enabled (which is the default), and the permission type
    696  // is not exempt from it, this will also create a separate default permission
    697  // for private browsing
    698  nsresult ImportDefaultEntry(const DefaultEntry& aDefaultEntry)
    699      MOZ_REQUIRES(mMonitor);
    700 
    701  nsresult Read(const MonitorAutoLock& aProofOfLock) MOZ_REQUIRES(mMonitor);
    702  void CompleteRead() MOZ_REQUIRES(mMonitor);
    703 
    704  void CompleteMigrations() MOZ_REQUIRES(mMonitor);
    705 
    706  Atomic<bool> mMemoryOnlyDB;
    707 
    708  nsTHashtable<PermissionHashKey> mPermissionTable MOZ_GUARDED_BY(mMonitor);
    709  // a unique, monotonically increasing id used to identify each database entry
    710  Atomic<int64_t> mLargestID;
    711 
    712  nsCOMPtr<nsIPrefBranch> mDefaultPrefBranch MOZ_GUARDED_BY(mMonitor);
    713 
    714  // NOTE: Ensure this is the last member since it has a large inline buffer.
    715  // An array to store the strings identifying the different types.
    716  Vector<nsCString, 512> mTypeArray MOZ_GUARDED_BY(mMonitor);
    717 
    718  nsCOMPtr<nsIThread> mThread MOZ_GUARDED_BY(mMonitor);
    719 
    720  struct ThreadBoundData {
    721    nsCOMPtr<mozIStorageConnection> mDBConn;
    722 
    723    nsCOMPtr<mozIStorageStatement> mStmtInsert;
    724    nsCOMPtr<mozIStorageStatement> mStmtDelete;
    725    nsCOMPtr<mozIStorageStatement> mStmtUpdate;
    726  };
    727  ThreadBound<ThreadBoundData> mThreadBoundData;
    728 };
    729 
    730 // {4F6B5E00-0C36-11d5-A535-0010A401EB10}
    731 #define NS_PERMISSIONMANAGER_CID \
    732  {0x4f6b5e00, 0xc36, 0x11d5, {0xa5, 0x35, 0x0, 0x10, 0xa4, 0x1, 0xeb, 0x10}}
    733 
    734 }  // namespace mozilla
    735 
    736 #endif  // mozilla_PermissionManager_h