tor-browser

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

ExtensionProtocolHandler.h (11090B)


      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 ExtensionProtocolHandler_h___
      7 #define ExtensionProtocolHandler_h___
      8 
      9 #include "mozilla/net/NeckoParent.h"
     10 #include "mozilla/LazyIdleThread.h"
     11 #include "mozilla/Result.h"
     12 #include "SubstitutingProtocolHandler.h"
     13 
     14 namespace mozilla {
     15 namespace net {
     16 
     17 class ExtensionStreamGetter;
     18 
     19 class ExtensionProtocolHandler final : public nsISubstitutingProtocolHandler,
     20                                       public SubstitutingProtocolHandler,
     21                                       public nsSupportsWeakReference {
     22 public:
     23  NS_DECL_ISUPPORTS_INHERITED
     24  NS_FORWARD_NSIPROTOCOLHANDLER(SubstitutingProtocolHandler::)
     25  NS_FORWARD_NSISUBSTITUTINGPROTOCOLHANDLER(SubstitutingProtocolHandler::)
     26 
     27  static already_AddRefed<ExtensionProtocolHandler> GetSingleton();
     28 
     29  /**
     30   * To be called in the parent process to obtain an input stream for a
     31   * a web accessible resource from an unpacked WebExtension dir.
     32   *
     33   * @param aChildURI a moz-extension URI sent from the child that refers
     34   *        to a web accessible resource file in an enabled unpacked extension
     35   * @param aTerminateSender out param set to true when the params are invalid
     36   *        and indicate the child should be terminated. If |aChildURI| is
     37   *        not a moz-extension URI, the child is in an invalid state and
     38   *        should be terminated.
     39   * @return NS_OK with |aTerminateSender| set to false on success. On
     40   *         failure, returns an error and sets |aTerminateSender| to indicate
     41   *         whether or not the child process should be terminated.
     42   *         A moz-extension URI from the child that doesn't resolve to a
     43   *         resource file within the extension could be the result of a bug
     44   *         in the extension and doesn't result in |aTerminateSender| being
     45   *         set to true.
     46   */
     47  Result<nsCOMPtr<nsIInputStream>, nsresult> NewStream(nsIURI* aChildURI,
     48                                                       bool* aTerminateSender);
     49 
     50  /**
     51   * To be called in the parent process to obtain a file descriptor for an
     52   * enabled WebExtension JAR file.
     53   *
     54   * @param aChildURI a moz-extension URI sent from the child that refers
     55   *        to a web accessible resource file in an enabled unpacked extension
     56   * @param aTerminateSender out param set to true when the params are invalid
     57   *        and indicate the child should be terminated. If |aChildURI| is
     58   *        not a moz-extension URI, the child is in an invalid state and
     59   *        should be terminated.
     60   * @param aPromise a promise that will be resolved asynchronously when the
     61   *        file descriptor is available.
     62   * @return NS_OK with |aTerminateSender| set to false on success. On
     63   *         failure, returns an error and sets |aTerminateSender| to indicate
     64   *         whether or not the child process should be terminated.
     65   *         A moz-extension URI from the child that doesn't resolve to an
     66   *         enabled WebExtension JAR could be the result of a bug in the
     67   *         extension and doesn't result in |aTerminateSender| being
     68   *         set to true.
     69   */
     70  Result<Ok, nsresult> NewFD(nsIURI* aChildURI, bool* aTerminateSender,
     71                             NeckoParent::GetExtensionFDResolver& aResolve);
     72 
     73 protected:
     74  ~ExtensionProtocolHandler() = default;
     75 
     76 private:
     77  explicit ExtensionProtocolHandler();
     78 
     79  [[nodiscard]] bool ResolveSpecialCases(const nsACString& aHost,
     80                                         const nsACString& aPath,
     81                                         const nsACString& aPathname,
     82                                         nsACString& aResult) override;
     83 
     84  // |result| is an inout param.  On entry to this function, *result
     85  // is expected to be non-null and already addrefed.  This function
     86  // may release the object stored in *result on entry and write
     87  // a new pointer to an already addrefed channel to *result.
     88  [[nodiscard]] virtual nsresult SubstituteChannel(
     89      nsIURI* uri, nsILoadInfo* aLoadInfo, nsIChannel** result) override;
     90 
     91  /**
     92   * For moz-extension URI's that resolve to file or JAR URI's, replaces
     93   * the provided channel with a channel that will proxy the load to the
     94   * parent process. For moz-extension URI's that resolve to other types
     95   * of URI's (not file or JAR), the provide channel is not replaced and
     96   * NS_OK is returned.
     97   *
     98   * @param aURI the moz-extension URI
     99   * @param aLoadInfo the loadinfo for the request
    100   * @param aRetVal in/out channel param referring to the channel that
    101   *        might need to be substituted with a remote channel.
    102   * @return NS_OK if the channel does not need to be substituted or
    103   *         or the replacement channel was created successfully.
    104   *         Otherwise returns an error.
    105   */
    106  Result<Ok, nsresult> SubstituteRemoteChannel(nsIURI* aURI,
    107                                               nsILoadInfo* aLoadInfo,
    108                                               nsIChannel** aRetVal);
    109 
    110  /**
    111   * Replaces a file channel with a remote file channel for loading a
    112   * web accessible resource for an unpacked extension from the parent.
    113   *
    114   * @param aURI the moz-extension URI
    115   * @param aLoadInfo the loadinfo for the request
    116   * @param aResolvedFileSpec the resolved URI spec for the file.
    117   * @param aRetVal in/out param referring to the new remote channel.
    118   *        The reference to the input param file channel is dropped and
    119   *        replaced with a reference to a new channel that remotes
    120   *        the file access. The new channel encapsulates a request to
    121   *        the parent for an IPCStream for the file.
    122   */
    123  void SubstituteRemoteFileChannel(nsIURI* aURI, nsILoadInfo* aLoadinfo,
    124                                   nsACString& aResolvedFileSpec,
    125                                   nsIChannel** aRetVal);
    126 
    127  /**
    128   * Replaces a JAR channel with a remote JAR channel for loading a
    129   * an extension JAR file from the parent.
    130   *
    131   * @param aURI the moz-extension URI
    132   * @param aLoadInfo the loadinfo for the request
    133   * @param aResolvedFileSpec the resolved URI spec for the file.
    134   * @param aRetVal in/out param referring to the new remote channel.
    135   *        The input param JAR channel is replaced with a new channel
    136   *        that remotes the JAR file access. The new channel encapsulates
    137   *        a request to the parent for the JAR file FD.
    138   */
    139  Result<Ok, nsresult> SubstituteRemoteJarChannel(nsIURI* aURI,
    140                                                  nsILoadInfo* aLoadinfo,
    141                                                  nsACString& aResolvedSpec,
    142                                                  nsIChannel** aRetVal);
    143 
    144  /**
    145   * Sets the aResult outparam to true if this unpacked extension load of
    146   * a resource that is outside the extension dir should be allowed. This
    147   * is only allowed for system extensions on Mac and Linux dev builds.
    148   *
    149   * @param aExtensionDir the extension directory. Argument must be an
    150   *        nsIFile for which Normalize() has already been called.
    151   * @param aRequestedFile the requested web-accessible resource file. Argument
    152   *        must be an nsIFile for which Normalize() has already been called.
    153   */
    154  Result<bool, nsresult> AllowExternalResource(nsIFile* aExtensionDir,
    155                                               nsIFile* aRequestedFile);
    156 
    157  // Set the channel's content type using the provided URI's type
    158  static void SetContentType(nsIURI* aURI, nsIChannel* aChannel);
    159 
    160  // Gets a SimpleChannel that wraps the provided ExtensionStreamGetter
    161  static void NewSimpleChannel(nsIURI* aURI, nsILoadInfo* aLoadinfo,
    162                               ExtensionStreamGetter* aStreamGetter,
    163                               nsIChannel** aRetVal);
    164 
    165  // Gets a SimpleChannel that wraps the provided channel
    166  static void NewSimpleChannel(nsIURI* aURI, nsILoadInfo* aLoadinfo,
    167                               nsIChannel* aChannel, nsIChannel** aRetVal);
    168 
    169 #if defined(XP_MACOSX)
    170  /**
    171   * Sets the aResult outparam to true if we are a developer build with the
    172   * repo dir environment variable set and the requested file resides in the
    173   * repo dir. Developer builds may load system extensions with web-accessible
    174   * resources that are symlinks to files in the repo dir. This method is for
    175   * checking if an unpacked resource requested by the child is from the repo.
    176   * The requested file must be already Normalized(). Only compile this for
    177   * Mac because the repo dir isn't always available on Linux.
    178   *
    179   * @param aRequestedFile the requested web-accessible resource file. Argument
    180   *        must be an nsIFile for which Normalize() has already been called.
    181   */
    182  Result<bool, nsresult> DevRepoContains(nsIFile* aRequestedFile);
    183 
    184  // On development builds, this points to development repo. Lazily set.
    185  nsCOMPtr<nsIFile> mDevRepo;
    186 
    187  // Set to true once we've already tried to load the dev repo path,
    188  // allowing for lazy initialization of |mDevRepo|.
    189  bool mAlreadyCheckedDevRepo{false};
    190 #endif /* XP_MACOSX */
    191 
    192 #if !defined(XP_WIN)
    193  /**
    194   * Sets the aResult outparam to true if we are a developer build and the
    195   * provided directory is within the NS_GRE_DIR directory. Developer builds
    196   * may load system extensions with web-accessible resources that are symlinks
    197   * to files outside of the extension dir to the repo dir. This method is for
    198   * checking if an extension directory is within NS_GRE_DIR. In that case, we
    199   * consider the extension a system extension and allow it to use symlinks to
    200   * resources outside of the extension dir. This exception is only applied
    201   * to loads for unpacked extensions in unpackaged developer builds.
    202   * The requested dir must be already Normalized().
    203   *
    204   * @param aExtensionDir the extension directory. Argument must be an
    205   *        nsIFile for which Normalize() has already been called.
    206   */
    207  Result<bool, nsresult> AppDirContains(nsIFile* aExtensionDir);
    208 
    209  // On development builds, cache the NS_GRE_DIR repo. Lazily set.
    210  nsCOMPtr<nsIFile> mAppDir;
    211 
    212  // Set to true once we've already read the AppDir, allowing for lazy
    213  // initialization of |mAppDir|.
    214  bool mAlreadyCheckedAppDir{false};
    215 #endif /* !defined(XP_WIN) */
    216 
    217  // Used for opening JAR files off the main thread when we just need to
    218  // obtain a file descriptor to send back to the child.
    219  RefPtr<mozilla::LazyIdleThread> mFileOpenerThread;
    220 
    221  // To allow parent IPDL actors to invoke methods on this handler when
    222  // handling moz-extension requests from the child.
    223  static StaticRefPtr<ExtensionProtocolHandler> sSingleton;
    224 
    225  // Set to true when this instance of the handler must proxy loads of
    226  // extension web-accessible resources to the parent process.
    227  bool mUseRemoteFileChannels;
    228 };
    229 
    230 }  // namespace net
    231 }  // namespace mozilla
    232 
    233 #endif /* ExtensionProtocolHandler_h___ */