tor-browser

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

changepassword.js (5894B)


      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 "use strict";
      5 
      6 const { XPCOMUtils } = ChromeUtils.importESModule(
      7  "resource://gre/modules/XPCOMUtils.sys.mjs"
      8 );
      9 
     10 ChromeUtils.defineLazyGetter(
     11  this,
     12  "l10n",
     13  () => new Localization(["security/pippki/pippki.ftl"], true)
     14 );
     15 
     16 var params;
     17 var token;
     18 var pw1;
     19 
     20 function doPrompt(messageL10nId) {
     21  let msg = l10n.formatValueSync(messageL10nId);
     22  Services.prompt.alert(window, null, msg);
     23 }
     24 
     25 function onLoad() {
     26  document.getElementById("set_password").getButton("accept").disabled = true;
     27  document.addEventListener("dialogaccept", setPassword);
     28 
     29  pw1 = document.getElementById("pw1");
     30  pw1.addEventListener("input", () => {
     31    setPasswordStrength();
     32    checkPasswords();
     33  });
     34 
     35  let pw2 = document.getElementById("pw2");
     36  pw2.addEventListener("input", () => {
     37    checkPasswords();
     38  });
     39 
     40  params = window.arguments[0].QueryInterface(Ci.nsIDialogParamBlock);
     41  token = params.objects.GetElementAt(0).QueryInterface(Ci.nsIPK11Token);
     42 
     43  document.l10n.setAttributes(
     44    document.getElementById("tokenName"),
     45    "change-password-token",
     46    { tokenName: token.tokenName }
     47  );
     48  process();
     49 }
     50 
     51 function process() {
     52  let bundle = document.getElementById("pippki_bundle");
     53  let oldpwbox = document.getElementById("oldpw");
     54  let msgBox = document.getElementById("message");
     55  // If the token is unitialized, don't use the old password box.
     56  // Otherwise, do.
     57  if ((token.needsLogin() && token.needsUserInit) || !token.needsLogin()) {
     58    oldpwbox.hidden = true;
     59    msgBox.setAttribute("value", bundle.getString("password_not_set"));
     60    msgBox.hidden = false;
     61 
     62    if (!token.needsLogin()) {
     63      oldpwbox.setAttribute("inited", "empty");
     64    } else {
     65      oldpwbox.setAttribute("inited", "true");
     66    }
     67 
     68    // Select first password field
     69    document.getElementById("pw1").focus();
     70  } else {
     71    // Select old password field
     72    oldpwbox.hidden = false;
     73    msgBox.hidden = true;
     74    oldpwbox.setAttribute("inited", "false");
     75    oldpwbox.focus();
     76  }
     77 
     78  // Return value 0 means "canceled"
     79  params.SetInt(1, 0);
     80 
     81  checkPasswords();
     82 }
     83 
     84 function setPassword(event) {
     85  var oldpwbox = document.getElementById("oldpw");
     86  var initpw = oldpwbox.getAttribute("inited");
     87 
     88  var success = false;
     89 
     90  if (initpw == "false" || initpw == "empty") {
     91    try {
     92      var oldpw = "";
     93      var passok = 0;
     94 
     95      if (initpw == "empty") {
     96        passok = 1;
     97      } else {
     98        oldpw = oldpwbox.value;
     99        passok = token.checkPassword(oldpw);
    100      }
    101 
    102      if (passok) {
    103        if (initpw == "empty" && pw1.value == "") {
    104          // checkPasswords() should have prevented this path from being reached.
    105        } else {
    106          if (pw1.value == "") {
    107            var secmoddb = Cc[
    108              "@mozilla.org/security/pkcs11moduledb;1"
    109            ].getService(Ci.nsIPKCS11ModuleDB);
    110            if (secmoddb.isFIPSEnabled) {
    111              // empty passwords are not allowed in FIPS mode
    112              doPrompt("pippki-pw-change2empty-in-fips-mode");
    113              passok = 0;
    114            }
    115          }
    116          if (passok) {
    117            token.changePassword(oldpw, pw1.value);
    118            if (pw1.value == "") {
    119              doPrompt("pippki-pw-erased-ok");
    120            } else {
    121              doPrompt("pippki-pw-change-ok");
    122            }
    123            success = true;
    124          }
    125        }
    126      } else {
    127        oldpwbox.focus();
    128        oldpwbox.setAttribute("value", "");
    129        doPrompt("pippki-incorrect-pw");
    130      }
    131    } catch (e) {
    132      doPrompt("pippki-failed-pw-change");
    133    }
    134  } else {
    135    token.initPassword(pw1.value);
    136    if (pw1.value == "") {
    137      doPrompt("pippki-pw-not-wanted");
    138    }
    139    success = true;
    140  }
    141 
    142  if (success && params) {
    143    // Return value 1 means "successfully executed ok"
    144    params.SetInt(1, 1);
    145  }
    146 
    147  // Terminate dialog
    148  if (!success) {
    149    event.preventDefault();
    150  }
    151 }
    152 
    153 function setPasswordStrength() {
    154  // We weigh the quality of the password by checking the number of:
    155  //  - Characters
    156  //  - Numbers
    157  //  - Non-alphanumeric chars
    158  //  - Upper and lower case characters
    159 
    160  let pw = document.getElementById("pw1").value;
    161 
    162  let pwlength = pw.length;
    163  if (pwlength > 5) {
    164    pwlength = 5;
    165  }
    166 
    167  let numnumeric = pw.replace(/[0-9]/g, "");
    168  let numeric = pw.length - numnumeric.length;
    169  if (numeric > 3) {
    170    numeric = 3;
    171  }
    172 
    173  let symbols = pw.replace(/\W/g, "");
    174  let numsymbols = pw.length - symbols.length;
    175  if (numsymbols > 3) {
    176    numsymbols = 3;
    177  }
    178 
    179  let numupper = pw.replace(/[A-Z]/g, "");
    180  let upper = pw.length - numupper.length;
    181  if (upper > 3) {
    182    upper = 3;
    183  }
    184 
    185  let pwstrength =
    186    pwlength * 10 - 20 + numeric * 10 + numsymbols * 15 + upper * 10;
    187 
    188  // Clamp strength to [0, 100].
    189  if (pwstrength < 0) {
    190    pwstrength = 0;
    191  }
    192  if (pwstrength > 100) {
    193    pwstrength = 100;
    194  }
    195 
    196  let meter = document.getElementById("pwmeter");
    197  meter.setAttribute("value", pwstrength);
    198 }
    199 
    200 function checkPasswords() {
    201  let pw1 = document.getElementById("pw1").value;
    202  let pw2 = document.getElementById("pw2").value;
    203 
    204  var oldpwbox = document.getElementById("oldpw");
    205  if (oldpwbox) {
    206    var initpw = oldpwbox.getAttribute("inited");
    207 
    208    if (initpw == "empty" && pw1 == "") {
    209      // The token has already been initialized, therefore this dialog
    210      // was called with the intention to change the password.
    211      // The token currently uses an empty password.
    212      // We will not allow changing the password from empty to empty.
    213      document.getElementById("set_password").getButton("accept").disabled =
    214        true;
    215      return;
    216    }
    217  }
    218 
    219  document.getElementById("set_password").getButton("accept").disabled =
    220    pw1 != pw2;
    221 }
    222 
    223 window.addEventListener("load", onLoad);