tor-browser

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

CookieStorage.h (10133B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #ifndef mozilla_net_CookieStorage_h
      7 #define mozilla_net_CookieStorage_h
      8 
      9 #include "CookieKey.h"
     10 
     11 #include "nsICookieNotification.h"
     12 #include "nsIObserver.h"
     13 #include "nsTHashtable.h"
     14 #include "nsWeakReference.h"
     15 #include <functional>
     16 #include "CookieCommons.h"
     17 
     18 class nsIArray;
     19 class nsICookie;
     20 class nsICookieTransactionCallback;
     21 class nsIPrefBranch;
     22 
     23 namespace mozilla {
     24 namespace net {
     25 
     26 class Cookie;
     27 class CookieParser;
     28 
     29 // Inherit from CookieKey so this can be stored in nsTHashTable
     30 // TODO: why aren't we using nsClassHashTable<CookieKey, ArrayType>?
     31 class CookieEntry : public CookieKey {
     32 public:
     33  // Hash methods
     34  using ArrayType = nsTArray<RefPtr<Cookie>>;
     35  using IndexType = ArrayType::index_type;
     36 
     37  explicit CookieEntry(KeyTypePointer aKey) : CookieKey(aKey) {}
     38 
     39  CookieEntry(const CookieEntry& toCopy) {
     40    // if we end up here, things will break. nsTHashtable shouldn't
     41    // allow this, since we set ALLOW_MEMMOVE to true.
     42    MOZ_ASSERT_UNREACHABLE("CookieEntry copy constructor is forbidden!");
     43  }
     44 
     45  ~CookieEntry() = default;
     46 
     47  inline ArrayType& GetCookies() { return mCookies; }
     48  inline const ArrayType& GetCookies() const { return mCookies; }
     49 
     50  size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const;
     51 
     52  bool IsPartitioned() const;
     53 
     54 private:
     55  ArrayType mCookies;
     56 };
     57 
     58 class CookieStorage : public nsIObserver, public nsSupportsWeakReference {
     59 public:
     60  NS_DECL_THREADSAFE_ISUPPORTS
     61  NS_DECL_NSIOBSERVER
     62 
     63  size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
     64 
     65  void GetCookies(nsTArray<RefPtr<nsICookie>>& aCookies) const;
     66 
     67  void GetSessionCookies(nsTArray<RefPtr<nsICookie>>& aCookies) const;
     68 
     69  already_AddRefed<Cookie> FindCookie(const nsACString& aBaseDomain,
     70                                      const OriginAttributes& aOriginAttributes,
     71                                      const nsACString& aHost,
     72                                      const nsACString& aName,
     73                                      const nsACString& aPath);
     74 
     75  uint32_t CountCookiesFromHost(const nsACString& aBaseDomain,
     76                                uint32_t aPrivateBrowsingId);
     77 
     78  uint32_t CountCookieBytesNotMatchingCookie(const Cookie& cookie,
     79                                             const nsACString& baseDomain);
     80 
     81  void GetAll(nsTArray<RefPtr<nsICookie>>& aResult) const;
     82 
     83  void GetCookiesFromHost(const nsACString& aBaseDomain,
     84                          const OriginAttributes& aOriginAttributes,
     85                          nsTArray<RefPtr<Cookie>>& aCookies);
     86 
     87  void GetCookiesWithOriginAttributes(const OriginAttributesPattern& aPattern,
     88                                      const nsACString& aBaseDomain,
     89                                      bool aSorted,
     90                                      nsTArray<RefPtr<nsICookie>>& aResult);
     91 
     92  void RemoveCookie(const nsACString& aBaseDomain,
     93                    const OriginAttributes& aOriginAttributes,
     94                    const nsACString& aHost, const nsACString& aName,
     95                    const nsACString& aPath, bool aFromHttp,
     96                    const nsID* aOperationID);
     97 
     98  virtual void RemoveCookiesWithOriginAttributes(
     99      const OriginAttributesPattern& aPattern, const nsACString& aBaseDomain);
    100 
    101  virtual void RemoveCookiesFromExactHost(
    102      const nsACString& aHost, const nsACString& aBaseDomain,
    103      const OriginAttributesPattern& aPattern);
    104 
    105  void RemoveAll();
    106 
    107  void NotifyChanged(nsISupports* aSubject,
    108                     nsICookieNotification::Action aAction,
    109                     const nsACString& aBaseDomain, bool aIsThirdParty = false,
    110                     dom::BrowsingContext* aBrowsingContext = nullptr,
    111                     bool aOldCookieIsSession = false,
    112                     const nsID* aOperationID = nullptr);
    113 
    114  void AddCookie(CookieParser* aCookieParser, const nsACString& aBaseDomain,
    115                 const OriginAttributes& aOriginAttributes, Cookie* aCookie,
    116                 int64_t aCurrentTimeInUsec, nsIURI* aHostURI,
    117                 const nsACString& aCookieHeader, bool aFromHttp,
    118                 bool aIsThirdParty, dom::BrowsingContext* aBrowsingContext,
    119                 const nsID* aOperationID = nullptr);
    120 
    121  uint32_t RemoveOldestCookies(CookieEntry* aEntry, bool aSecure,
    122                               uint32_t aBytesToRemove,
    123                               nsCOMPtr<nsIArray>& aPurgedList);
    124 
    125  void RemoveOlderCookiesByBytes(CookieEntry* aEntry, uint32_t removeBytes,
    126                                 nsCOMPtr<nsIArray>& aPurgedList);
    127 
    128  // tracks how far over the hard and soft CHIPS limits
    129  // we use the hard and soft limit to prevent excessive purging.
    130  // the soft limit (aka quota) is derived directly from partitionLimitCapacity
    131  // pref while the hard limit is the softLimit * a factor
    132  // (kChipsHardLimitFactor). the hard limit is used to trigger purging and when
    133  // we do purge, we purge down to the soft limit (quota)
    134  struct ChipsLimitExcess {
    135    uint32_t hard;
    136    uint32_t soft;  // aka quota
    137  };
    138 
    139  ChipsLimitExcess PartitionLimitExceededBytes(Cookie* aCookie,
    140                                               const nsACString& aBaseDomain);
    141 
    142  static void CreateOrUpdatePurgeList(nsCOMPtr<nsIArray>& aPurgedList,
    143                                      nsICookie* aCookie);
    144 
    145  virtual void StaleCookies(const nsTArray<RefPtr<Cookie>>& aCookieList,
    146                            int64_t aCurrentTimeInUsec) = 0;
    147 
    148  virtual void Close() = 0;
    149 
    150  virtual void EnsureInitialized() = 0;
    151 
    152  virtual nsresult RunInTransaction(
    153      nsICookieTransactionCallback* aCallback) = 0;
    154 
    155 protected:
    156  // stores the CookieEntry entryclass and an index into the cookie array within
    157  // that entryclass, for purposes of storing an iteration state that points to
    158  // a certain cookie.
    159  struct MOZ_STACK_CLASS CookieListIter {
    160    // default (non-initializing) constructor.
    161    CookieListIter() = default;
    162 
    163    // explicit constructor to a given iterator state with entryclass 'aEntry'
    164    // and index 'aIndex'.
    165    explicit CookieListIter(CookieEntry* aEntry, CookieEntry::IndexType aIndex)
    166        : entry(aEntry), index(aIndex) {}
    167 
    168    // get the Cookie * the iterator currently points to.
    169    mozilla::net::Cookie* Cookie() const { return entry->GetCookies()[index]; }
    170 
    171    CookieEntry* entry;
    172    CookieEntry::IndexType index;
    173  };
    174 
    175  // comparator class for lastaccessed times of cookies.
    176  class CompareCookiesByAge;
    177 
    178  // Cookie comparator for the priority queue used in FindStaleCookies.
    179  // Note that the expired cookie has the highest priority.
    180  // Other non-expired cookies are sorted by their age.
    181  class CookieIterComparator;
    182 
    183  // comparator class for sorting cookies by entry and index.
    184  class CompareCookiesByIndex;
    185 
    186  CookieStorage() = default;
    187  virtual ~CookieStorage() = default;
    188 
    189  void Init();
    190 
    191  bool FindCookie(const nsACString& aBaseDomain,
    192                  const OriginAttributes& aOriginAttributes,
    193                  const nsACString& aHost, const nsACString& aName,
    194                  const nsACString& aPath, CookieListIter& aIter);
    195 
    196  void AddCookieToList(const nsACString& aBaseDomain,
    197                       const OriginAttributes& aOriginAttributes,
    198                       Cookie* aCookie);
    199 
    200  virtual void StoreCookie(const nsACString& aBaseDomain,
    201                           const OriginAttributes& aOriginAttributes,
    202                           Cookie* aCookie) = 0;
    203 
    204  virtual const char* NotificationTopic() const = 0;
    205 
    206  virtual void NotifyChangedInternal(nsICookieNotification* aSubject,
    207                                     bool aOldCookieIsSession) = 0;
    208 
    209  virtual void RemoveAllInternal() = 0;
    210 
    211  // This method calls RemoveCookieFromDB + RemoveCookieFromListInternal.
    212  void RemoveCookieFromList(const CookieListIter& aIter);
    213 
    214  void RemoveCookieFromListInternal(const CookieListIter& aIter);
    215 
    216  virtual void RemoveCookieFromDB(const Cookie& aCookie) = 0;
    217 
    218  already_AddRefed<nsIArray> PurgeCookiesWithCallbacks(
    219      int64_t aCurrentTimeInUsec, uint16_t aMaxNumberOfCookies,
    220      int64_t aCookiePurgeAge,
    221      std::function<void(const CookieListIter&)>&& aRemoveCookieCallback,
    222      std::function<void()>&& aFinalizeCallback);
    223 
    224  nsTHashtable<CookieEntry> mHostTable;
    225 
    226  uint32_t mCookieCount{0};
    227 
    228 private:
    229  void PrefChanged(nsIPrefBranch* aPrefBranch);
    230 
    231  bool FindSecureCookie(const nsACString& aBaseDomain,
    232                        const OriginAttributes& aOriginAttributes,
    233                        Cookie* aCookie);
    234 
    235  static void FindStaleCookies(CookieEntry* aEntry, int64_t aCurrentTimeInMSec,
    236                               bool aIsSecure,
    237                               nsTArray<CookieListIter>& aOutput,
    238                               uint32_t aLimit);
    239 
    240  void UpdateCookieOldestTime(Cookie* aCookie);
    241 
    242  void MergeCookieSchemeMap(Cookie* aOldCookie, Cookie* aNewCookie);
    243 
    244  static already_AddRefed<nsIArray> CreatePurgeList(nsICookie* aCookie);
    245 
    246  virtual already_AddRefed<nsIArray> PurgeCookies(int64_t aCurrentTimeInUsec,
    247                                                  uint16_t aMaxNumberOfCookies,
    248                                                  int64_t aCookiePurgeAge) = 0;
    249 
    250  void RemoveCookiesFromBack(nsTArray<CookieListIter>& aCookieIters,
    251                             nsCOMPtr<nsIArray>& aPurgedList);
    252 
    253  // Serialize aBaseDomain e.g. apply "zero abbreveation" (::), use single
    254  // zeros and remove brackets to match principal base domain representation.
    255  static bool SerializeIPv6BaseDomain(nsACString& aBaseDomain);
    256 
    257  virtual void CollectCookieJarSizeData() = 0;
    258 
    259  int64_t mCookieOldestTime{INT64_MAX};
    260 
    261  uint16_t mMaxNumberOfCookies{kMaxNumberOfCookies};
    262  uint16_t mMaxCookiesPerHost{kMaxCookiesPerHost};
    263  uint16_t mCookieQuotaPerHost{kCookieQuotaPerHost};
    264  int64_t mCookiePurgeAge{kCookiePurgeAge};
    265 };
    266 
    267 }  // namespace net
    268 }  // namespace mozilla
    269 
    270 #endif  // mozilla_net_CookieStorage_h