tor-browser

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

IPPAutoStart.sys.mjs (5021B)


      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 import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
      6 
      7 const lazy = {};
      8 
      9 ChromeUtils.defineESModuleGetters(lazy, {
     10  IPProtectionServerlist:
     11    "moz-src:///browser/components/ipprotection/IPProtectionServerlist.sys.mjs",
     12  IPPProxyManager:
     13    "moz-src:///browser/components/ipprotection/IPPProxyManager.sys.mjs",
     14  IPPProxyStates:
     15    "moz-src:///browser/components/ipprotection/IPPProxyManager.sys.mjs",
     16  IPProtectionService:
     17    "moz-src:///browser/components/ipprotection/IPProtectionService.sys.mjs",
     18  IPProtectionStates:
     19    "moz-src:///browser/components/ipprotection/IPProtectionService.sys.mjs",
     20 });
     21 
     22 const AUTOSTART_FEATURE_ENABLE_PREF = "browser.ipProtection.features.autoStart";
     23 const AUTOSTART_PREF = "browser.ipProtection.autoStartEnabled";
     24 
     25 /**
     26 * This class monitors the auto-start pref and if it sees a READY state, it
     27 * calls `start()`. This is done only if the previous state was not a ACTIVE
     28 * because, in that case, more likely the VPN on/off state is an user decision.
     29 */
     30 class IPPAutoStartSingleton {
     31  #shouldStartWhenReady = false;
     32 
     33  constructor() {
     34    XPCOMUtils.defineLazyPreferenceGetter(
     35      this,
     36      "autoStartPref",
     37      AUTOSTART_PREF,
     38      false,
     39      (_pref, _oldVal, featureEnabled) => {
     40        if (featureEnabled) {
     41          this.init();
     42        } else {
     43          this.uninit();
     44        }
     45      }
     46    );
     47 
     48    XPCOMUtils.defineLazyPreferenceGetter(
     49      this,
     50      "autoStartFeatureEnablePref",
     51      AUTOSTART_FEATURE_ENABLE_PREF,
     52      false
     53    );
     54  }
     55 
     56  init() {
     57    if (this.autoStart && !this.handleEvent) {
     58      this.handleEvent = this.#handleEvent.bind(this);
     59      this.#shouldStartWhenReady = true;
     60 
     61      lazy.IPProtectionService.addEventListener(
     62        "IPProtectionService:StateChanged",
     63        this.handleEvent
     64      );
     65    }
     66  }
     67 
     68  initOnStartupCompleted() {}
     69 
     70  uninit() {
     71    if (this.handleEvent) {
     72      lazy.IPProtectionService.removeEventListener(
     73        "IPProtectionService:StateChanged",
     74        this.handleEvent
     75      );
     76 
     77      delete this.handleEvent;
     78      this.#shouldStartWhenReady = false;
     79    }
     80  }
     81 
     82  get autoStart() {
     83    // We activate the auto-start feature only if the pref is true and we have
     84    // the serverlist already.
     85    return (
     86      this.autoStartFeatureEnablePref &&
     87      this.autoStartPref &&
     88      lazy.IPProtectionServerlist.hasList
     89    );
     90  }
     91 
     92  #handleEvent(_event) {
     93    switch (lazy.IPProtectionService.state) {
     94      case lazy.IPProtectionStates.UNINITIALIZED:
     95      case lazy.IPProtectionStates.UNAVAILABLE:
     96      case lazy.IPProtectionStates.UNAUTHENTICATED:
     97        this.#shouldStartWhenReady = true;
     98        break;
     99 
    100      case lazy.IPProtectionStates.READY:
    101        if (this.#shouldStartWhenReady) {
    102          this.#shouldStartWhenReady = false;
    103          lazy.IPPProxyManager.start(/* user action: */ false);
    104        }
    105        break;
    106 
    107      default:
    108        break;
    109    }
    110  }
    111 }
    112 
    113 const IPPAutoStart = new IPPAutoStartSingleton();
    114 
    115 /**
    116 * This class monitors the startup phases and registers/unregisters the channel
    117 * filter to avoid data leak. The activation of the VPN is done by the
    118 * IPPAutoStart object above.
    119 */
    120 class IPPEarlyStartupFilter {
    121  #autoStartAndAtStartup = false;
    122 
    123  constructor() {
    124    this.handleEvent = this.#handleEvent.bind(this);
    125    this.#autoStartAndAtStartup = IPPAutoStart.autoStart;
    126  }
    127 
    128  init() {
    129    if (this.#autoStartAndAtStartup) {
    130      lazy.IPPProxyManager.createChannelFilter();
    131 
    132      lazy.IPProtectionService.addEventListener(
    133        "IPProtectionService:StateChanged",
    134        this.handleEvent
    135      );
    136      lazy.IPPProxyManager.addEventListener(
    137        "IPPProxyManager:StateChanged",
    138        this.handleEvent
    139      );
    140    }
    141  }
    142 
    143  initOnStartupCompleted() {}
    144 
    145  uninit() {
    146    if (this.autoStartAndAtStartup) {
    147      this.#autoStartAndAtStartup = false;
    148 
    149      lazy.IPPProxyManager.removeEventListener(
    150        "IPPProxyManager:StateChanged",
    151        this.handleEvent
    152      );
    153      lazy.IPProtectionService.removeEventListener(
    154        "IPProtectionService:StateChanged",
    155        this.handleEvent
    156      );
    157    }
    158  }
    159 
    160  #cancelChannelFilter() {
    161    lazy.IPPProxyManager.cancelChannelFilter();
    162  }
    163 
    164  #handleEvent(_event) {
    165    switch (lazy.IPProtectionService.state) {
    166      case lazy.IPProtectionStates.UNAVAILABLE:
    167      case lazy.IPProtectionStates.UNAUTHENTICATED:
    168        // These states block the auto-start at startup.
    169        this.#cancelChannelFilter();
    170        this.uninit();
    171        break;
    172 
    173      default:
    174        // Let's ignoring any other state.
    175        break;
    176    }
    177 
    178    if (lazy.IPPProxyManager.state === lazy.IPPProxyStates.ACTIVE) {
    179      // We have completed our task.
    180      this.uninit();
    181    }
    182  }
    183 }
    184 
    185 const IPPAutoStartHelpers = [IPPAutoStart, new IPPEarlyStartupFilter()];
    186 
    187 export { IPPAutoStartHelpers };