tor-browser

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

test_auth_dialog_permission.js (7163B)


      1 // This file tests authentication prompt depending on pref
      2 // network.auth.subresource-http-auth-allow:
      3 //   0 - don't allow sub-resources to open HTTP authentication credentials
      4 //       dialogs
      5 //   1 - allow sub-resources to open HTTP authentication credentials dialogs,
      6 //       but don't allow it for cross-origin sub-resources
      7 //   2 - allow the cross-origin authentication as well.
      8 
      9 "use strict";
     10 
     11 const { HttpServer } = ChromeUtils.importESModule(
     12  "resource://testing-common/httpd.sys.mjs"
     13 );
     14 
     15 var prefs = Services.prefs;
     16 
     17 // Since this test creates a TYPE_DOCUMENT channel via javascript, it will
     18 // end up using the wrong LoadInfo constructor. Setting this pref will disable
     19 // the ContentPolicyType assertion in the constructor.
     20 prefs.setBoolPref("network.loadinfo.skip_type_assertion", true);
     21 
     22 function authHandler(metadata, response) {
     23  // btoa("guest:guest"), but that function is not available here
     24  var expectedHeader = "Basic Z3Vlc3Q6Z3Vlc3Q=";
     25 
     26  var body;
     27  if (
     28    metadata.hasHeader("Authorization") &&
     29    metadata.getHeader("Authorization") == expectedHeader
     30  ) {
     31    response.setStatusLine(metadata.httpVersion, 200, "OK, authorized");
     32    response.setHeader("WWW-Authenticate", 'Basic realm="secret"', false);
     33    response.setHeader("Content-Type", "text/javascript", false);
     34 
     35    body = "success";
     36  } else {
     37    // didn't know guest:guest, failure
     38    response.setStatusLine(metadata.httpVersion, 401, "Unauthorized");
     39    response.setHeader("WWW-Authenticate", 'Basic realm="secret"', false);
     40    response.setHeader("Content-Type", "text/javascript", false);
     41 
     42    body = "failed";
     43  }
     44 
     45  response.bodyOutputStream.write(body, body.length);
     46 }
     47 
     48 var httpserv = new HttpServer();
     49 httpserv.registerPathHandler("/auth", authHandler);
     50 httpserv.start(-1);
     51 
     52 ChromeUtils.defineLazyGetter(this, "URL", function () {
     53  return "http://localhost:" + httpserv.identity.primaryPort;
     54 });
     55 
     56 function AuthPrompt(promptExpected) {
     57  this.promptExpected = promptExpected;
     58 }
     59 
     60 AuthPrompt.prototype = {
     61  user: "guest",
     62  pass: "guest",
     63 
     64  QueryInterface: ChromeUtils.generateQI(["nsIAuthPrompt"]),
     65 
     66  prompt() {
     67    do_throw("unexpected prompt call");
     68  },
     69 
     70  promptUsernameAndPassword(title, text, realm, savePW, user, pw) {
     71    Assert.ok(this.promptExpected, "Not expected the authentication prompt.");
     72 
     73    user.value = this.user;
     74    pw.value = this.pass;
     75    return true;
     76  },
     77 
     78  promptPassword() {
     79    do_throw("unexpected promptPassword call");
     80  },
     81 };
     82 
     83 function Requestor(promptExpected) {
     84  this.promptExpected = promptExpected;
     85 }
     86 
     87 Requestor.prototype = {
     88  QueryInterface: ChromeUtils.generateQI(["nsIInterfaceRequestor"]),
     89 
     90  getInterface(iid) {
     91    if (iid.equals(Ci.nsIAuthPrompt)) {
     92      this.prompter = new AuthPrompt(this.promptExpected);
     93      return this.prompter;
     94    }
     95 
     96    throw Components.Exception("", Cr.NS_ERROR_NO_INTERFACE);
     97  },
     98 
     99  prompter: null,
    100 };
    101 
    102 function make_uri(url) {
    103  return Services.io.newURI(url);
    104 }
    105 
    106 function makeChan(loadingUrl, url, contentPolicy) {
    107  var uri = make_uri(loadingUrl);
    108  var principal = Services.scriptSecurityManager.createContentPrincipal(
    109    uri,
    110    {}
    111  );
    112 
    113  return NetUtil.newChannel({
    114    uri: url,
    115    loadingPrincipal: principal,
    116    securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT,
    117    contentPolicyType: contentPolicy,
    118  }).QueryInterface(Ci.nsIHttpChannel);
    119 }
    120 
    121 function Test(
    122  subresource_http_auth_allow_pref,
    123  loadingUri,
    124  uri,
    125  contentPolicy,
    126  expectedCode
    127 ) {
    128  this._subresource_http_auth_allow_pref = subresource_http_auth_allow_pref;
    129  this._loadingUri = loadingUri;
    130  this._uri = uri;
    131  this._contentPolicy = contentPolicy;
    132  this._expectedCode = expectedCode;
    133 }
    134 
    135 Test.prototype = {
    136  _subresource_http_auth_allow_pref: 1,
    137  _loadingUri: null,
    138  _uri: null,
    139  _contentPolicy: Ci.nsIContentPolicy.TYPE_OTHER,
    140  _expectedCode: 200,
    141 
    142  onStartRequest(request) {
    143    try {
    144      if (!Components.isSuccessCode(request.status)) {
    145        do_throw("Channel should have a success code!");
    146      }
    147 
    148      if (!(request instanceof Ci.nsIHttpChannel)) {
    149        do_throw("Expecting an HTTP channel");
    150      }
    151 
    152      Assert.equal(request.responseStatus, this._expectedCode);
    153      // The request should be succeeded iff we expect 200
    154      Assert.equal(request.requestSucceeded, this._expectedCode == 200);
    155    } catch (e) {
    156      do_throw("Unexpected exception: " + e);
    157    }
    158 
    159    throw Components.Exception("", Cr.NS_ERROR_ABORT);
    160  },
    161 
    162  onDataAvailable() {
    163    do_throw("Should not get any data!");
    164  },
    165 
    166  onStopRequest(request, status) {
    167    Assert.equal(status, Cr.NS_ERROR_ABORT);
    168 
    169    // Clear the auth cache.
    170    Cc["@mozilla.org/network/http-auth-manager;1"]
    171      .getService(Ci.nsIHttpAuthManager)
    172      .clearAll();
    173 
    174    do_timeout(0, run_next_test);
    175  },
    176 
    177  run() {
    178    dump(
    179      "Run test: " +
    180        this._subresource_http_auth_allow_pref +
    181        this._loadingUri +
    182        this._uri +
    183        this._contentPolicy +
    184        this._expectedCode +
    185        " \n"
    186    );
    187 
    188    prefs.setIntPref(
    189      "network.auth.subresource-http-auth-allow",
    190      this._subresource_http_auth_allow_pref
    191    );
    192    let chan = makeChan(this._loadingUri, this._uri, this._contentPolicy);
    193    chan.notificationCallbacks = new Requestor(this._expectedCode == 200);
    194    chan.asyncOpen(this);
    195  },
    196 };
    197 
    198 var tests = [
    199  // For the next 3 tests the preference is set to 2 - allow the cross-origin
    200  // authentication as well.
    201 
    202  // A cross-origin request.
    203  new Test(
    204    2,
    205    "http://example.com",
    206    URL + "/auth",
    207    Ci.nsIContentPolicy.TYPE_OTHER,
    208    200
    209  ),
    210  // A non cross-origin sub-resource request.
    211  new Test(2, URL + "/", URL + "/auth", Ci.nsIContentPolicy.TYPE_OTHER, 200),
    212  // A top level document.
    213  new Test(
    214    2,
    215    URL + "/auth",
    216    URL + "/auth",
    217    Ci.nsIContentPolicy.TYPE_DOCUMENT,
    218    200
    219  ),
    220 
    221  // For the next 3 tests the preference is set to 1 - allow sub-resources to
    222  // open HTTP authentication credentials dialogs, but don't allow it for
    223  // cross-origin sub-resources
    224 
    225  // A cross-origin request.
    226  new Test(
    227    1,
    228    "http://example.com",
    229    URL + "/auth",
    230    Ci.nsIContentPolicy.TYPE_OTHER,
    231    401
    232  ),
    233  // A non cross-origin sub-resource request.
    234  new Test(1, URL + "/", URL + "/auth", Ci.nsIContentPolicy.TYPE_OTHER, 200),
    235  // A top level document.
    236  new Test(
    237    1,
    238    URL + "/auth",
    239    URL + "/auth",
    240    Ci.nsIContentPolicy.TYPE_DOCUMENT,
    241    200
    242  ),
    243 
    244  // For the next 3 tests the preference is set to 0 - don't allow sub-resources
    245  // to open HTTP authentication credentials dialogs.
    246 
    247  // A cross-origin request.
    248  new Test(
    249    0,
    250    "http://example.com",
    251    URL + "/auth",
    252    Ci.nsIContentPolicy.TYPE_OTHER,
    253    401
    254  ),
    255  // A sub-resource request.
    256  new Test(0, URL + "/", URL + "/auth", Ci.nsIContentPolicy.TYPE_OTHER, 401),
    257  // A top level request.
    258  new Test(
    259    0,
    260    URL + "/auth",
    261    URL + "/auth",
    262    Ci.nsIContentPolicy.TYPE_DOCUMENT,
    263    200
    264  ),
    265 ];
    266 
    267 function run_next_test() {
    268  var nextTest = tests.shift();
    269  if (!nextTest) {
    270    httpserv.stop(do_test_finished);
    271    return;
    272  }
    273 
    274  nextTest.run();
    275 }
    276 
    277 function run_test() {
    278  do_test_pending();
    279  run_next_test();
    280 }