tor-browser

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

auth.js (6401B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 loader.lazyRequireGetter(
      8  this,
      9  "prompt",
     10  "resource://devtools/shared/security/prompt.js"
     11 );
     12 
     13 /**
     14 * A simple enum-like object with keys mirrored to values.
     15 * This makes comparison to a specfic value simpler without having to repeat and
     16 * mis-type the value.
     17 */
     18 function createEnum(obj) {
     19  for (const key in obj) {
     20    obj[key] = key;
     21  }
     22  return obj;
     23 }
     24 
     25 /**
     26 * |allowConnection| implementations can return various values as their |result|
     27 * field to indicate what action to take.  By specifying these, we can
     28 * centralize the common actions available, while still allowing embedders to
     29 * present their UI in whatever way they choose.
     30 */
     31 var AuthenticationResult = (exports.AuthenticationResult = createEnum({
     32  /**
     33   * Close all listening sockets, and disable them from opening again.
     34   */
     35  DISABLE_ALL: null,
     36 
     37  /**
     38   * Deny the current connection.
     39   */
     40  DENY: null,
     41 
     42  /**
     43   * Additional data needs to be exchanged before a result can be determined.
     44   */
     45  PENDING: null,
     46 
     47  /**
     48   * Allow the current connection.
     49   */
     50  ALLOW: null,
     51 
     52  /**
     53   * Allow the current connection, and persist this choice for future
     54   * connections from the same client.  This requires a trustable mechanism to
     55   * identify the client in the future.
     56   */
     57  ALLOW_PERSIST: null,
     58 }));
     59 
     60 /**
     61 * An |Authenticator| implements an authentication mechanism via various hooks
     62 * in the client and server debugger socket connection path (see socket.js).
     63 *
     64 * |Authenticator|s are stateless objects.  Each hook method is passed the state
     65 * it needs by the client / server code in socket.js.
     66 *
     67 * Separate instances of the |Authenticator| are created for each use (client
     68 * connection, server listener) in case some methods are customized by the
     69 * embedder for a given use case.
     70 */
     71 var Authenticators = {};
     72 
     73 /**
     74 * The Prompt authenticator displays a server-side user prompt that includes
     75 * connection details, and asks the user to verify the connection.  There are
     76 * no cryptographic properties at work here, so it is up to the user to be sure
     77 * that the client can be trusted.
     78 */
     79 var Prompt = (Authenticators.Prompt = {});
     80 
     81 Prompt.mode = "PROMPT";
     82 
     83 Prompt.Client = class {
     84  mode = Prompt.mode;
     85 
     86  /**
     87   * When client is about to make a new connection, verify that the connection settings
     88   * are compatible with this authenticator.
     89   *
     90   * @throws if validation requirements are not met
     91   */
     92  validateSettings() {}
     93 
     94  /**
     95   * When client has just made a new socket connection, validate the connection
     96   * to ensure it meets the authenticator's policies.
     97   *
     98   * @param host string
     99   *        The host name or IP address of the devtools server.
    100   * @param port number
    101   *        The port number of the devtools server.
    102   * @param encryption boolean (optional)
    103   *        Whether the server requires encryption.  Defaults to false.
    104   * @param s nsISocketTransport
    105   *        Underlying socket transport, in case more details are needed.
    106   * @return boolean
    107   *         Whether the connection is valid.
    108   */
    109  validateConnection() {
    110    return true;
    111  }
    112 
    113  /**
    114   * Work with the server to complete any additional steps required by this
    115   * authenticator's policies.
    116   *
    117   * Debugging commences after this hook completes successfully.
    118   *
    119   * @param host string
    120   *        The host name or IP address of the devtools server.
    121   * @param port number
    122   *        The port number of the devtools server.
    123   * @param encryption boolean (optional)
    124   *        Whether the server requires encryption.  Defaults to false.
    125   * @param transport DebuggerTransport
    126   *        A transport that can be used to communicate with the server.
    127   * @return A promise can be used if there is async behavior.
    128   */
    129  authenticate() {}
    130 };
    131 
    132 Prompt.Server = class {
    133  mode = Prompt.mode;
    134 
    135  /**
    136   * Augment the service discovery advertisement with any additional data needed
    137   * to support this authentication mode.
    138   *
    139   * @param listener SocketListener
    140   *        The socket listener that was just opened.
    141   * @param advertisement object
    142   *        The advertisement being built.
    143   */
    144  augmentAdvertisement(listener, advertisement) {
    145    advertisement.authentication = Prompt.mode;
    146  }
    147 
    148  /**
    149   * Determine whether a connection the server should be allowed or not based on
    150   * this authenticator's policies.
    151   *
    152   * @param session object
    153   *        In PROMPT mode, the |session| includes:
    154   *        {
    155   *          client: {
    156   *            host,
    157   *            port
    158   *          },
    159   *          server: {
    160   *            host,
    161   *            port
    162   *          },
    163   *          transport
    164   *        }
    165   * @return An AuthenticationResult value.
    166   *         A promise that will be resolved to the above is also allowed.
    167   */
    168  authenticate({ client, server }) {
    169    if (!Services.prefs.getBoolPref("devtools.debugger.prompt-connection")) {
    170      return AuthenticationResult.ALLOW;
    171    }
    172    return this.allowConnection({
    173      authentication: this.mode,
    174      client,
    175      server,
    176    });
    177  }
    178 
    179  /**
    180   * Prompt the user to accept or decline the incoming connection.  The default
    181   * implementation is used unless this is overridden on a particular
    182   * authenticator instance.
    183   *
    184   * It is expected that the implementation of |allowConnection| will show a
    185   * prompt to the user so that they can allow or deny the connection.
    186   *
    187   * @param session object
    188   *        In PROMPT mode, the |session| includes:
    189   *        {
    190   *          authentication: "PROMPT",
    191   *          client: {
    192   *            host,
    193   *            port
    194   *          },
    195   *          server: {
    196   *            host,
    197   *            port
    198   *          }
    199   *        }
    200   * @return An AuthenticationResult value.
    201   *         A promise that will be resolved to the above is also allowed.
    202   */
    203  allowConnection = prompt.Server.defaultAllowConnection;
    204 };
    205 
    206 exports.Authenticators = {
    207  get(mode) {
    208    if (!mode) {
    209      mode = Prompt.mode;
    210    }
    211    for (const key in Authenticators) {
    212      const auth = Authenticators[key];
    213      if (auth.mode === mode) {
    214        return auth;
    215      }
    216    }
    217    throw new Error("Unknown authenticator mode: " + mode);
    218  },
    219 };