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