tor-browser

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

PermissionDelegateHandler.h (7796B)


      1 /* -*- Mode: C++; tab-width: 2; 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 /*
      8 * Permission delegate handler provides a policy of how top-level can
      9 * delegate permission to embedded iframes.
     10 *
     11 * This class includes a mechanism to delegate permission using feature
     12 * policy. Feature policy will assure that only cross-origin iframes which
     13 * have been explicitly granted access will have the opportunity to request
     14 * permission.
     15 *
     16 * For example if an iframe has not been granted access to geolocation by
     17 * Feature Policy, geolocation request from the iframe will be automatically
     18 * denied. if the top-level origin already has access to geolocation and the
     19 * iframe has been granted access to geolocation by Feature Policy, the iframe
     20 * will also have access to geolocation. If the top-level frame did not have
     21 * access to geolocation, and the iframe has been granted access to geolocation
     22 * by Feature Policy, a request from the cross-origin iframe would trigger a
     23 * prompt using of the top-level origin.
     24 */
     25 
     26 #ifndef mozilla_PermissionDelegateHandler_h
     27 #define mozilla_PermissionDelegateHandler_h
     28 
     29 #include "mozilla/Array.h"
     30 #include "nsCycleCollectionParticipant.h"
     31 #include "nsISupports.h"
     32 #include "nsIPermissionDelegateHandler.h"
     33 #include "nsIPermissionManager.h"
     34 #include "nsCOMPtr.h"
     35 
     36 class nsIPrincipal;
     37 class nsIContentPermissionRequest;
     38 
     39 namespace mozilla {
     40 namespace dom {
     41 class Document;
     42 class WindowContext;
     43 }  // namespace dom
     44 
     45 class PermissionDelegateHandler final : public nsIPermissionDelegateHandler {
     46 public:
     47  NS_DECL_CYCLE_COLLECTING_ISUPPORTS_FINAL
     48  NS_DECL_CYCLE_COLLECTION_CLASS(PermissionDelegateHandler)
     49 
     50  NS_DECL_NSIPERMISSIONDELEGATEHANDLER
     51 
     52  explicit PermissionDelegateHandler() = default;
     53  explicit PermissionDelegateHandler(mozilla::dom::Document* aDocument);
     54 
     55  static constexpr size_t DELEGATED_PERMISSION_COUNT = 15;
     56 
     57  typedef struct DelegatedPermissionList {
     58    Array<uint32_t, DELEGATED_PERMISSION_COUNT> mPermissions;
     59 
     60    bool operator==(const DelegatedPermissionList& aOther) const {
     61      return mPermissions == aOther.mPermissions;
     62    }
     63  } DelegatedPermissionList;
     64 
     65  bool Initialize();
     66 
     67  /*
     68   * Indicates if we has the right to make permission request with aType
     69   */
     70  bool HasPermissionDelegated(const nsACString& aType) const;
     71 
     72  /*
     73   * Get permission state, which applied permission delegate policy.
     74   *
     75   * @param aType the permission type to get
     76   * @param aPermission out argument which will be a permission type that we
     77   *                    will return from this function.
     78   * @param aExactHostMatch whether to look for the exact host name or also for
     79   *                        subdomains that can have the same permission.
     80   */
     81  nsresult GetPermission(const nsACString& aType, uint32_t* aPermission,
     82                         bool aExactHostMatch);
     83 
     84  /*
     85   * Get permission state for permission api, which applied
     86   * permission delegate policy.
     87   *
     88   * @param aType the permission type to get
     89   * @param aExactHostMatch whether to look for the exact host name or also for
     90   *                        subdomains that can have the same permission.
     91   * @param aPermission out argument which will be a permission type that we
     92   *                    will return from this function.
     93   */
     94  nsresult GetPermissionForPermissionsAPI(const nsACString& aType,
     95                                          uint32_t* aPermission);
     96 
     97  enum PermissionDelegatePolicy {
     98    /* Always delegate permission from top level to iframe and the iframe
     99     * should use top level origin to get/set permission.*/
    100    eDelegateUseTopOrigin,
    101 
    102    /* Permission is delegated using Feature Policy. Permission is denied by
    103     * default in cross origin iframe and the iframe only could get/set
    104     * permission if there's allow attribute set in iframe. e.g allow =
    105     * "geolocation" */
    106    eDelegateUseFeaturePolicy,
    107 
    108    /* Persistent denied permissions in cross origin iframe */
    109    ePersistDeniedCrossOrigin,
    110 
    111    /* This is the old behavior of cross origin iframe permission. The
    112     * permission delegation should not have an effect on iframe. The cross
    113     * origin iframe get/set permissions by its origin */
    114    eDelegateUseIframeOrigin,
    115  };
    116 
    117  /*
    118   * Indicates matching between Feature Policy and Permissions name defined in
    119   * Permissions Manager, not DOM Permissions API. Permissions API exposed in
    120   * DOM only supports "geo" at the moment but Permissions Manager also supports
    121   * "camera", "microphone".
    122   */
    123  typedef struct {
    124    const char* mPermissionName;
    125    const char16_t* mFeatureName;
    126    PermissionDelegatePolicy mPolicy;
    127  } PermissionDelegateInfo;
    128 
    129  /**
    130   * The loader maintains a weak reference to the document with
    131   * which it is initialized. This call forces the reference to
    132   * be dropped.
    133   */
    134  void DropDocumentReference() { mDocument = nullptr; }
    135 
    136  /*
    137   * Helper function to return the delegate info value for aPermissionName.
    138   * @param aPermissionName the permission name to get
    139   */
    140  static const PermissionDelegateInfo* GetPermissionDelegateInfo(
    141      const nsAString& aPermissionName);
    142 
    143  /*
    144   * Helper function to return the delegate principal. This will return nullptr,
    145   * or request's principal or top level principal based on the delegate policy
    146   * will be applied for a given type.
    147   * We use this function when prompting, no need to perform permission check
    148   * (deny/allow).
    149   *
    150   * @param aType the permission type to get
    151   * @param aRequest  The request which the principal is get from.
    152   * @param aResult out argument which will be a principal that we
    153   *                will return from this function.
    154   */
    155  static nsresult GetDelegatePrincipal(const nsACString& aType,
    156                                       nsIContentPermissionRequest* aRequest,
    157                                       nsIPrincipal** aResult);
    158 
    159  /**
    160   * Populate all delegated permissions to the WindowContext of the associated
    161   * document. We only populate the permissions for the top-level content.
    162   */
    163  void PopulateAllDelegatedPermissions();
    164 
    165  /**
    166   * Update the given delegated permission to the WindowContext. We only
    167   * update it for the top-level content.
    168   */
    169  void UpdateDelegatedPermission(const nsACString& aType);
    170 
    171 private:
    172  ~PermissionDelegateHandler() = default;
    173 
    174  /*
    175   * Check whether the permission is blocked by FeaturePolicy directive.
    176   * Default allowlist for a featureName of permission used in permissions
    177   * delegate should be set to eSelf, to ensure that permission is denied by
    178   * default and only have the opportunity to request permission with allow
    179   * attribute.
    180   */
    181  bool HasFeaturePolicyAllowed(const PermissionDelegateInfo* info) const;
    182 
    183  /**
    184   * A helper function to test the permission and set the result to the given
    185   * list. It will return true if the permission is changed, otherwise false.
    186   */
    187  bool UpdateDelegatePermissionInternal(
    188      PermissionDelegateHandler::DelegatedPermissionList& aList,
    189      const nsACString& aType, size_t aIdx,
    190      nsresult (NS_STDCALL nsIPermissionManager::*aTestFunc)(nsIPrincipal*,
    191                                                             const nsACString&,
    192                                                             uint32_t*));
    193 
    194  // A weak pointer to our document. Nulled out by DropDocumentReference.
    195  mozilla::dom::Document* mDocument;
    196 
    197  nsCOMPtr<nsIPrincipal> mPrincipal;
    198  RefPtr<nsIPermissionManager> mPermissionManager;
    199 };
    200 
    201 }  // namespace mozilla
    202 
    203 #endif  // mozilla_PermissionDelegateHandler_h