LCOV - code coverage report
Current view: top level - extensions/cookie - nsPermissionManager.h (source / functions) Hit Total Coverage
Test: output.info Lines: 37 43 86.0 %
Date: 2017-07-14 16:53:18 Functions: 16 17 94.1 %
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 nsPermissionManager_h__
       8             : #define nsPermissionManager_h__
       9             : 
      10             : #include "nsIPermissionManager.h"
      11             : #include "nsIObserver.h"
      12             : #include "nsWeakReference.h"
      13             : #include "nsCOMPtr.h"
      14             : #include "nsIInputStream.h"
      15             : #include "nsTHashtable.h"
      16             : #include "nsTArray.h"
      17             : #include "nsString.h"
      18             : #include "nsPermission.h"
      19             : #include "nsHashKeys.h"
      20             : #include "nsCOMArray.h"
      21             : #include "nsDataHashtable.h"
      22             : #include "nsIRunnable.h"
      23             : #include "nsRefPtrHashtable.h"
      24             : #include "mozilla/MozPromise.h"
      25             : 
      26             : namespace mozilla {
      27             : class OriginAttributesPattern;
      28             : }
      29             : 
      30             : class nsIPermission;
      31             : class mozIStorageConnection;
      32             : class mozIStorageAsyncStatement;
      33             : 
      34             : ////////////////////////////////////////////////////////////////////////////////
      35             : 
      36             : class nsPermissionManager final : public nsIPermissionManager,
      37             :                                   public nsIObserver,
      38             :                                   public nsSupportsWeakReference
      39             : {
      40             : public:
      41             :   class PermissionEntry
      42             :   {
      43             :   public:
      44          14 :     PermissionEntry(int64_t aID, uint32_t aType, uint32_t aPermission,
      45             :                     uint32_t aExpireType, int64_t aExpireTime,
      46             :                     int64_t aModificationTime)
      47          14 :      : mID(aID)
      48             :      , mType(aType)
      49             :      , mPermission(aPermission)
      50             :      , mExpireType(aExpireType)
      51             :      , mExpireTime(aExpireTime)
      52             :      , mModificationTime(aModificationTime)
      53             :      , mNonSessionPermission(aPermission)
      54             :      , mNonSessionExpireType(aExpireType)
      55          14 :      , mNonSessionExpireTime(aExpireTime)
      56          14 :     {}
      57             : 
      58             :     int64_t  mID;
      59             :     uint32_t mType;
      60             :     uint32_t mPermission;
      61             :     uint32_t mExpireType;
      62             :     int64_t  mExpireTime;
      63             :     int64_t  mModificationTime;
      64             :     uint32_t mNonSessionPermission;
      65             :     uint32_t mNonSessionExpireType;
      66             :     uint32_t mNonSessionExpireTime;
      67             :   };
      68             : 
      69             :   /**
      70             :    * PermissionKey is the key used by PermissionHashKey hash table.
      71             :    *
      72             :    * NOTE: It could be implementing nsIHashable but there is no reason to worry
      73             :    * with XPCOM interfaces while we don't need to.
      74             :    */
      75             :   class PermissionKey
      76             :   {
      77             :   public:
      78             :     static PermissionKey* CreateFromPrincipal(nsIPrincipal* aPrincipal,
      79             :                                               nsresult& aResult);
      80             :     static PermissionKey* CreateFromURI(nsIURI* aURI,
      81             :                                         nsresult& aResult);
      82             : 
      83          16 :     explicit PermissionKey(const nsACString& aOrigin)
      84          16 :       : mOrigin(aOrigin)
      85             :     {
      86          16 :     }
      87             : 
      88           2 :     bool operator==(const PermissionKey& aKey) const {
      89           2 :       return mOrigin.Equals(aKey.mOrigin);
      90             :     }
      91             : 
      92          16 :     PLDHashNumber GetHashCode() const {
      93          16 :       return mozilla::HashString(mOrigin);
      94             :     }
      95             : 
      96          60 :     NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PermissionKey)
      97             : 
      98             :     nsCString mOrigin;
      99             : 
     100             :   private:
     101             :     // Default ctor shouldn't be used.
     102             :     PermissionKey() = delete;
     103             : 
     104             :     // Dtor shouldn't be used outside of the class.
     105           4 :     ~PermissionKey() {};
     106             :   };
     107             : 
     108           6 :   class PermissionHashKey : public nsRefPtrHashKey<PermissionKey>
     109             :   {
     110             :   public:
     111          12 :     explicit PermissionHashKey(const PermissionKey* aPermissionKey)
     112          12 :       : nsRefPtrHashKey<PermissionKey>(aPermissionKey)
     113          12 :     {}
     114             : 
     115           6 :     PermissionHashKey(const PermissionHashKey& toCopy)
     116           6 :       : nsRefPtrHashKey<PermissionKey>(toCopy)
     117           6 :       , mPermissions(toCopy.mPermissions)
     118           6 :     {}
     119             : 
     120           2 :     bool KeyEquals(const PermissionKey* aKey) const
     121             :     {
     122           2 :       return *aKey == *GetKey();
     123             :     }
     124             : 
     125          16 :     static PLDHashNumber HashKey(const PermissionKey* aKey)
     126             :     {
     127          16 :       return aKey->GetHashCode();
     128             :     }
     129             : 
     130             :     // Force the hashtable to use the copy constructor when shuffling entries
     131             :     // around, otherwise the Auto part of our AutoTArray won't be happy!
     132             :     enum { ALLOW_MEMMOVE = false };
     133             : 
     134          38 :     inline nsTArray<PermissionEntry> & GetPermissions()
     135             :     {
     136          38 :       return mPermissions;
     137             :     }
     138             : 
     139          14 :     inline int32_t GetPermissionIndex(uint32_t aType) const
     140             :     {
     141          16 :       for (uint32_t i = 0; i < mPermissions.Length(); ++i)
     142           2 :         if (mPermissions[i].mType == aType)
     143           0 :           return i;
     144             : 
     145          14 :       return -1;
     146             :     }
     147             : 
     148           0 :     inline PermissionEntry GetPermission(uint32_t aType) const
     149             :     {
     150           0 :       for (uint32_t i = 0; i < mPermissions.Length(); ++i)
     151           0 :         if (mPermissions[i].mType == aType)
     152           0 :           return mPermissions[i];
     153             : 
     154             :       // unknown permission... return relevant data
     155             :       return PermissionEntry(-1, aType, nsIPermissionManager::UNKNOWN_ACTION,
     156           0 :                              nsIPermissionManager::EXPIRE_NEVER, 0, 0);
     157             :     }
     158             : 
     159             :   private:
     160             :     AutoTArray<PermissionEntry, 1> mPermissions;
     161             :   };
     162             : 
     163             :   // nsISupports
     164             :   NS_DECL_ISUPPORTS
     165             :   NS_DECL_NSIPERMISSIONMANAGER
     166             :   NS_DECL_NSIOBSERVER
     167             : 
     168             :   nsPermissionManager();
     169             :   static nsIPermissionManager* GetXPCOMSingleton();
     170             :   nsresult Init();
     171             : 
     172             :   // enums for AddInternal()
     173             :   enum OperationType {
     174             :     eOperationNone,
     175             :     eOperationAdding,
     176             :     eOperationRemoving,
     177             :     eOperationChanging,
     178             :     eOperationReplacingDefault
     179             :   };
     180             : 
     181             :   enum DBOperationType {
     182             :     eNoDBOperation,
     183             :     eWriteToDB
     184             :   };
     185             : 
     186             :   enum NotifyOperationType {
     187             :     eDontNotify,
     188             :     eNotify
     189             :   };
     190             : 
     191             :   // A special value for a permission ID that indicates the ID was loaded as
     192             :   // a default value.  These will never be written to the database, but may
     193             :   // be overridden with an explicit permission (including UNKNOWN_ACTION)
     194             :   static const int64_t cIDPermissionIsDefault = -1;
     195             : 
     196             :   nsresult AddInternal(nsIPrincipal* aPrincipal,
     197             :                        const nsCString& aType,
     198             :                        uint32_t aPermission,
     199             :                        int64_t aID,
     200             :                        uint32_t aExpireType,
     201             :                        int64_t  aExpireTime,
     202             :                        int64_t aModificationTime,
     203             :                        NotifyOperationType aNotifyOperation,
     204             :                        DBOperationType aDBOperation,
     205             :                        const bool aIgnoreSessionPermissions = false);
     206             : 
     207             :   /**
     208             :    * Initialize the "clear-origin-attributes-data" observing.
     209             :    * Will create a nsPermissionManager instance if needed.
     210             :    * That way, we can prevent have nsPermissionManager created at startup just
     211             :    * to be able to clear data when an application is uninstalled.
     212             :    */
     213             :   static void ClearOriginDataObserverInit();
     214             : 
     215             :   nsresult
     216             :   RemovePermissionsWithAttributes(mozilla::OriginAttributesPattern& aAttrs);
     217             : 
     218             :   /**
     219             :    * See `nsIPermissionManager::GetPermissionsWithKey` for more info on
     220             :    * permission keys.
     221             :    *
     222             :    * Get the permission key corresponding to the given Principal. This method is
     223             :    * intentionally infallible, as we want to provide an permission key to every
     224             :    * principal. Principals which don't have meaningful URIs with http://,
     225             :    * https://, or ftp:// schemes are given the default "" Permission Key.
     226             :    *
     227             :    * @param aPrincipal  The Principal which the key is to be extracted from.
     228             :    * @param aPermissionKey  A string which will be filled with the permission key.
     229             :    */
     230             :   static void GetKeyForPrincipal(nsIPrincipal* aPrincipal, nsACString& aPermissionKey);
     231             : 
     232             :   /**
     233             :    * See `nsIPermissionManager::GetPermissionsWithKey` for more info on
     234             :    * permission keys.
     235             :    *
     236             :    * Get the permission key corresponding to the given Origin. This method is
     237             :    * like GetKeyForPrincipal, except that it avoids creating a nsIPrincipal
     238             :    * object when you already have access to an origin string.
     239             :    *
     240             :    * If this method is passed a nonsensical origin string it may produce a
     241             :    * nonsensical permission key result.
     242             :    *
     243             :    * @param aOrigin  The origin which the key is to be extracted from.
     244             :    * @param aPermissionKey  A string which will be filled with the permission key.
     245             :    */
     246             :   static void GetKeyForOrigin(const nsACString& aOrigin, nsACString& aPermissionKey);
     247             : 
     248             :   /**
     249             :    * See `nsIPermissionManager::GetPermissionsWithKey` for more info on
     250             :    * permission keys.
     251             :    *
     252             :    * Get the permission key corresponding to the given Principal and type. This
     253             :    * method is intentionally infallible, as we want to provide an permission key
     254             :    * to every principal. Principals which don't have meaningful URIs with
     255             :    * http://, https://, or ftp:// schemes are given the default "" Permission
     256             :    * Key.
     257             :    *
     258             :    * This method is different from GetKeyForPrincipal in that it also takes
     259             :    * permissions which must be sent down before loading a document into account.
     260             :    *
     261             :    * @param aPrincipal  The Principal which the key is to be extracted from.
     262             :    * @param aType  The type of the permission to get the key for.
     263             :    * @param aPermissionKey  A string which will be filled with the permission key.
     264             :    */
     265             :   static void GetKeyForPermission(nsIPrincipal* aPrincipal,
     266             :                                   const char* aType,
     267             :                                   nsACString& aPermissionKey);
     268             : 
     269             :   /**
     270             :    * See `nsIPermissionManager::GetPermissionsWithKey` for more info on
     271             :    * permission keys.
     272             :    *
     273             :    * Get all permissions keys which could correspond to the given principal.
     274             :    * This method, like GetKeyForPrincipal, is infallible and should always
     275             :    * produce at least one key.
     276             :    *
     277             :    * Unlike GetKeyForPrincipal, this method also gets the keys for base domains
     278             :    * of the given principal. All keys returned by this method must be avaliable
     279             :    * in the content process for a given URL to successfully have its permissions
     280             :    * checked in the `aExactHostMatch = false` situation.
     281             :    *
     282             :    * @param aPrincipal  The Principal which the key is to be extracted from.
     283             :    */
     284             :   static nsTArray<nsCString> GetAllKeysForPrincipal(nsIPrincipal* aPrincipal);
     285             : 
     286             : private:
     287             :   virtual ~nsPermissionManager();
     288             : 
     289             :   int32_t GetTypeIndex(const char *aTypeString,
     290             :                        bool        aAdd);
     291             : 
     292             :   PermissionHashKey* GetPermissionHashKey(nsIPrincipal* aPrincipal,
     293             :                                           uint32_t      aType,
     294             :                                           bool          aExactHostMatch);
     295             :   PermissionHashKey* GetPermissionHashKey(nsIURI*       aURI,
     296             :                                           uint32_t      aType,
     297             :                                           bool          aExactHostMatch);
     298             : 
     299          14 :   nsresult CommonTestPermission(nsIPrincipal* aPrincipal,
     300             :                                 const char  * aType,
     301             :                                 uint32_t    * aPermission,
     302             :                                 bool          aExactHostMatch,
     303             :                                 bool          aIncludingSession)
     304             :   {
     305          14 :     return CommonTestPermissionInternal(aPrincipal, nullptr, aType,
     306             :                                         aPermission, aExactHostMatch,
     307          14 :                                         aIncludingSession);
     308             :   }
     309           6 :   nsresult CommonTestPermission(nsIURI    * aURI,
     310             :                                 const char* aType,
     311             :                                 uint32_t  * aPermission,
     312             :                                 bool        aExactHostMatch,
     313             :                                 bool        aIncludingSession)
     314             :   {
     315           6 :     return CommonTestPermissionInternal(nullptr, aURI, aType, aPermission,
     316           6 :                                         aExactHostMatch, aIncludingSession);
     317             :   }
     318             :   // Only one of aPrincipal or aURI is allowed to be passed in.
     319             :   nsresult CommonTestPermissionInternal(nsIPrincipal* aPrincipal,
     320             :                                         nsIURI      * aURI,
     321             :                                         const char  * aType,
     322             :                                         uint32_t    * aPermission,
     323             :                                         bool          aExactHostMatch,
     324             :                                         bool          aIncludingSession);
     325             : 
     326             :   nsresult OpenDatabase(nsIFile* permissionsFile);
     327             :   nsresult InitDB(bool aRemoveFile);
     328             :   nsresult CreateTable();
     329             :   nsresult Import();
     330             :   nsresult ImportDefaults();
     331             :   nsresult _DoImport(nsIInputStream *inputStream, mozIStorageConnection *aConn);
     332             :   nsresult Read();
     333             :   void     NotifyObserversWithPermission(nsIPrincipal*     aPrincipal,
     334             :                                          const nsCString  &aType,
     335             :                                          uint32_t          aPermission,
     336             :                                          uint32_t          aExpireType,
     337             :                                          int64_t           aExpireTime,
     338             :                                          const char16_t  *aData);
     339             :   void     NotifyObservers(nsIPermission *aPermission, const char16_t *aData);
     340             : 
     341             :   // Finalize all statements, close the DB and null it.
     342             :   // if aRebuildOnSuccess, reinitialize database
     343             :   void     CloseDB(bool aRebuildOnSuccess = false);
     344             : 
     345             :   nsresult RemoveAllInternal(bool aNotifyObservers);
     346             :   nsresult RemoveAllFromMemory();
     347             :   static void UpdateDB(OperationType aOp,
     348             :                        mozIStorageAsyncStatement* aStmt,
     349             :                        int64_t aID,
     350             :                        const nsACString& aOrigin,
     351             :                        const nsACString& aType,
     352             :                        uint32_t aPermission,
     353             :                        uint32_t aExpireType,
     354             :                        int64_t aExpireTime,
     355             :                        int64_t aModificationTime);
     356             : 
     357             :   /**
     358             :    * This method removes all permissions modified after the specified time.
     359             :    */
     360             :   nsresult
     361             :   RemoveAllModifiedSince(int64_t aModificationTime);
     362             : 
     363             :   /**
     364             :    * Returns false if this permission manager wouldn't have the permission
     365             :    * requested avaliable.
     366             :    *
     367             :    * If aType is nullptr, checks that the permission manager would have all
     368             :    * permissions avaliable for the given principal.
     369             :    */
     370             :   bool PermissionAvaliable(nsIPrincipal* aPrincipal, const char* aType);
     371             : 
     372             :   nsRefPtrHashtable<nsCStringHashKey, mozilla::GenericPromise::Private> mPermissionKeyPromiseMap;
     373             : 
     374             :   nsCOMPtr<mozIStorageConnection> mDBConn;
     375             :   nsCOMPtr<mozIStorageAsyncStatement> mStmtInsert;
     376             :   nsCOMPtr<mozIStorageAsyncStatement> mStmtDelete;
     377             :   nsCOMPtr<mozIStorageAsyncStatement> mStmtUpdate;
     378             : 
     379             :   bool mMemoryOnlyDB;
     380             : 
     381             :   nsTHashtable<PermissionHashKey> mPermissionTable;
     382             :   // a unique, monotonically increasing id used to identify each database entry
     383             :   int64_t                      mLargestID;
     384             : 
     385             :   // An array to store the strings identifying the different types.
     386             :   nsTArray<nsCString>          mTypeArray;
     387             : 
     388             :   // Initially, |false|. Set to |true| once shutdown has started, to avoid
     389             :   // reopening the database.
     390             :   bool mIsShuttingDown;
     391             : 
     392             :   friend class DeleteFromMozHostListener;
     393             :   friend class CloseDatabaseListener;
     394             : };
     395             : 
     396             : // {4F6B5E00-0C36-11d5-A535-0010A401EB10}
     397             : #define NS_PERMISSIONMANAGER_CID \
     398             : { 0x4f6b5e00, 0xc36, 0x11d5, { 0xa5, 0x35, 0x0, 0x10, 0xa4, 0x1, 0xeb, 0x10 } }
     399             : 
     400             : #endif /* nsPermissionManager_h__ */

Generated by: LCOV version 1.13