tor-browser

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

head.js (3826B)


      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 https://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 const { IPProtectionService, IPProtectionStates } = ChromeUtils.importESModule(
      8  "moz-src:///browser/components/ipprotection/IPProtectionService.sys.mjs"
      9 );
     10 const { IPPProxyManager, IPPProxyStates } = ChromeUtils.importESModule(
     11  "moz-src:///browser/components/ipprotection/IPPProxyManager.sys.mjs"
     12 );
     13 const { IPPSignInWatcher } = ChromeUtils.importESModule(
     14  "moz-src:///browser/components/ipprotection/IPPSignInWatcher.sys.mjs"
     15 );
     16 const { ProxyPass } = ChromeUtils.importESModule(
     17  "moz-src:///browser/components/ipprotection/GuardianClient.sys.mjs"
     18 );
     19 const { RemoteSettings } = ChromeUtils.importESModule(
     20  "resource://services-settings/remote-settings.sys.mjs"
     21 );
     22 
     23 const { sinon } = ChromeUtils.importESModule(
     24  "resource://testing-common/Sinon.sys.mjs"
     25 );
     26 
     27 function waitForEvent(target, eventName, callback = () => true) {
     28  return new Promise(resolve => {
     29    let listener = event => {
     30      if (callback()) {
     31        target.removeEventListener(eventName, listener);
     32        resolve(event);
     33      }
     34    };
     35    target.addEventListener(eventName, listener);
     36  });
     37 }
     38 
     39 async function putServerInRemoteSettings(
     40  server = {
     41    hostname: "test1.example.com",
     42    port: 443,
     43    quarantined: false,
     44  }
     45 ) {
     46  const TEST_US_CITY = {
     47    name: "Test City",
     48    code: "TC",
     49    servers: [server],
     50  };
     51  const US = {
     52    name: "United States",
     53    code: "US",
     54    cities: [TEST_US_CITY],
     55  };
     56  do_get_profile();
     57  const client = RemoteSettings("vpn-serverlist");
     58  await client.db.clear();
     59  await client.db.create(US);
     60  await client.db.importChanges({}, Date.now());
     61 }
     62 /* exported putServerInRemoteSettings */
     63 
     64 function setupStubs(
     65  sandbox,
     66  options = {
     67    signedIn: true,
     68    isLinkedToGuardian: true,
     69    validProxyPass: true,
     70    entitlement: {
     71      subscribed: false,
     72      uid: 42,
     73      created_at: "2023-01-01T12:00:00.000Z",
     74    },
     75  }
     76 ) {
     77  sandbox.stub(IPPSignInWatcher, "isSignedIn").get(() => options.signedIn);
     78  sandbox
     79    .stub(IPProtectionService.guardian, "isLinkedToGuardian")
     80    .resolves(options.isLinkedToGuardian);
     81  sandbox.stub(IPProtectionService.guardian, "fetchUserInfo").resolves({
     82    status: 200,
     83    error: null,
     84    entitlement: options.entitlement,
     85  });
     86  sandbox.stub(IPProtectionService.guardian, "enroll").resolves({
     87    status: 200,
     88    error: null,
     89  });
     90  sandbox.stub(IPProtectionService.guardian, "fetchProxyPass").resolves({
     91    status: 200,
     92    error: undefined,
     93    pass: new ProxyPass(
     94      options.validProxyPass
     95        ? createProxyPassToken()
     96        : createExpiredProxyPassToken()
     97    ),
     98  });
     99 }
    100 
    101 /**
    102 * Creates a Token that can be fed as a Network Response from Guardian
    103 * to simulate a Proxy Pass.
    104 *
    105 * @param {Temporal.Instant} from
    106 * @param {Temporal.Instant} until
    107 * @returns {string} JWT Token
    108 */
    109 function createProxyPassToken(
    110  from = Temporal.Now.instant(),
    111  until = from.add({ hours: 24 })
    112 ) {
    113  const header = {
    114    alg: "HS256",
    115    typ: "JWT",
    116  };
    117  const body = {
    118    iat: Math.floor(from.add({ seconds: 1 }).epochMilliseconds / 1000),
    119    nbf: Math.floor(from.epochMilliseconds / 1000),
    120    exp: Math.floor(until.epochMilliseconds / 1000),
    121    sub: "proxy-pass-user-42",
    122    aud: "guardian-proxy",
    123    iss: "vpn.mozilla.org",
    124  };
    125  const encode = obj => btoa(JSON.stringify(obj));
    126  return [encode(header), encode(body), "signature"].join(".");
    127 }
    128 /* exported createExpiredProxyPassToken */
    129 function createExpiredProxyPassToken() {
    130  return createProxyPassToken(
    131    Temporal.Now.instant().subtract({ hours: 2 }),
    132    Temporal.Now.instant().subtract({ hours: 1 })
    133  );
    134 }
    135 /* exported createExpiredProxyPassToken */