security/manager/pki/resources/content/device_manager.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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/. */
     5 const nsIFilePicker = Components.interfaces.nsIFilePicker;
     6 const nsFilePicker = "@mozilla.org/filepicker;1";
     7 const nsIPKCS11Slot = Components.interfaces.nsIPKCS11Slot;
     8 const nsIPKCS11Module = Components.interfaces.nsIPKCS11Module;
     9 const nsPKCS11ModuleDB = "@mozilla.org/security/pkcs11moduledb;1";
    10 const nsIPKCS11ModuleDB = Components.interfaces.nsIPKCS11ModuleDB;
    11 const nsIPK11Token = Components.interfaces.nsIPK11Token;
    12 const nsPK11TokenDB = "@mozilla.org/security/pk11tokendb;1";
    13 const nsIPK11TokenDB = Components.interfaces.nsIPK11TokenDB;
    14 const nsIDialogParamBlock = Components.interfaces.nsIDialogParamBlock;
    15 const nsDialogParamBlock = "@mozilla.org/embedcomp/dialogparam;1";
    16 const nsIPKCS11 = Components.interfaces.nsIPKCS11;
    17 const nsPKCS11ContractID = "@mozilla.org/security/pkcs11;1";
    19 var bundle;
    20 var secmoddb;
    21 var skip_enable_buttons = false;
    23 /* Do the initial load of all PKCS# modules and list them. */
    24 function LoadModules()
    25 {
    26   bundle = document.getElementById("pippki_bundle");
    27   secmoddb = Components.classes[nsPKCS11ModuleDB].getService(nsIPKCS11ModuleDB);
    28   window.crypto.enableSmartCardEvents = true;
    29   document.addEventListener("smartcard-insert", onSmartCardChange, false);
    30   document.addEventListener("smartcard-remove", onSmartCardChange, false);
    32   RefreshDeviceList();
    33 }
    35 function getPKCS11()
    36 {
    37   return Components.classes[nsPKCS11ContractID].getService(nsIPKCS11);
    38 }
    40 function getNSSString(name)
    41 {
    42   return document.getElementById("pipnss_bundle").getString(name);
    43 }
    45 function doPrompt(msg)
    46 {
    47   let prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
    48     getService(Components.interfaces.nsIPromptService);
    49   prompts.alert(window, null, msg);
    50 }
    52 function doConfirm(msg)
    53 {
    54   let prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
    55     getService(Components.interfaces.nsIPromptService);
    56   return prompts.confirm(window, null, msg);
    57 }
    59 function RefreshDeviceList()
    60 {
    61   var modules = secmoddb.listModules();
    62   var done = false;
    64   try {
    65     modules.isDone();
    66   } catch (e) { done = true; }
    67   while (!done) {
    68     var module = modules.currentItem().QueryInterface(nsIPKCS11Module);
    69     if (module) {
    70       var slotnames = [];
    71       var slots = module.listSlots();
    72       var slots_done = false;
    73       try {
    74         slots.isDone();
    75       } catch (e) { slots_done = true; }
    76       while (!slots_done) {
    77         var slot = null;
    78  	try {
    79           slot = slots.currentItem().QueryInterface(nsIPKCS11Slot);
    80         } catch (e) { slot = null; }
    81         // in the ongoing discussion of whether slot names or token names
    82         // are to be shown, I've gone with token names because NSS will
    83         // prefer lookup by token name.  However, the token may not be
    84         // present, so maybe slot names should be listed, while token names
    85         // are "remembered" for lookup?
    86 	if (slot != null) {
    87           if (slot.tokenName)
    88             slotnames[slotnames.length] = slot.tokenName;
    89           else
    90             slotnames[slotnames.length] = slot.name;
    91 	}
    92         try {
    93           slots.next();
    94         } catch (e) { slots_done = true; }
    95       }
    96       AddModule(module.name, slotnames);
    97     }
    98     try {
    99       modules.next();
   100     } catch (e) { done = true; }
   101   }
   102   /* Set the text on the fips button */
   103   SetFIPSButton();
   104 }
   106 function SetFIPSButton()
   107 {
   108   var fipsButton = document.getElementById("fipsbutton");
   109   var label;
   110   if (secmoddb.isFIPSEnabled) {
   111    label = bundle.getString("disable_fips");
   112   } else {
   113    label = bundle.getString("enable_fips");
   114   }
   115   fipsButton.setAttribute("label", label);
   117   var can_toggle = secmoddb.canToggleFIPS;
   118   if (can_toggle) {
   119     fipsButton.removeAttribute("disabled");
   120   } else {
   121     fipsButton.setAttribute("disabled", "true");
   122   }
   123 }
   125 /* Add a module to the tree.  slots is the array of slots in the module,
   126  * to be represented as children.
   127  */
   128 function AddModule(module, slots)
   129 {
   130   var tree = document.getElementById("device_list");
   131   var item  = document.createElement("treeitem");
   132   var row  = document.createElement("treerow");
   133   var cell = document.createElement("treecell");
   134   cell.setAttribute("label", module);
   135   row.appendChild(cell);
   136   item.appendChild(row);
   137   var parent = document.createElement("treechildren");
   138   for (var i = 0; i<slots.length; i++) {
   139     var child_item = document.createElement("treeitem");
   140     var child_row = document.createElement("treerow");
   141     var child_cell = document.createElement("treecell");
   142     child_cell.setAttribute("label", slots[i]);
   143     child_row.appendChild(child_cell);
   144     child_item.appendChild(child_row);
   145     child_item.setAttribute("pk11kind", "slot");
   146     parent.appendChild(child_item);
   147   }
   148   item.appendChild(parent);
   149   item.setAttribute("pk11kind", "module");
   150   item.setAttribute("open", "true");
   151   item.setAttribute("container", "true");
   152   tree.appendChild(item);
   153 }
   155 var selected_slot;
   156 var selected_module;
   158 /* get the slot selected by the user (can only be one-at-a-time) */
   159 function getSelectedItem()
   160 {
   161   var tree = document.getElementById('device_tree');
   162   if (tree.currentIndex < 0) return;
   163   var item = tree.contentView.getItemAtIndex(tree.currentIndex);
   164   selected_slot = null;
   165   selected_module = null;
   166   if (item) {
   167     var kind = item.getAttribute("pk11kind");
   168     var module_name;
   169     if (kind == "slot") {
   170       // get the module cell for this slot cell
   171       var cell = item.parentNode.parentNode.firstChild.firstChild;
   172       module_name = cell.getAttribute("label");
   173       var module = secmoddb.findModuleByName(module_name);
   174       // get the cell for the selected row (the slot to display)
   175       cell = item.firstChild.firstChild;
   176       var slot_name = cell.getAttribute("label");
   177       selected_slot = module.findSlotByName(slot_name);
   178     } else { // (kind == "module")
   179       // get the cell for the selected row (the module to display)
   180       cell = item.firstChild.firstChild;
   181       module_name = cell.getAttribute("label");
   182       selected_module = secmoddb.findModuleByName(module_name);
   183     }
   184   }
   185 }
   187 function enableButtons()
   188 {
   189   if (skip_enable_buttons)
   190     return;
   192   var login_toggle = "true";
   193   var logout_toggle = "true";
   194   var pw_toggle = "true";
   195   var unload_toggle = "true";
   196   getSelectedItem();
   197   if (selected_module) {
   198     unload_toggle = "false";
   199     showModuleInfo();
   200   } else if (selected_slot) {
   201     // here's the workaround - login functions are all with token,
   202     // so grab the token type
   203     var selected_token = selected_slot.getToken();
   204     if (selected_token != null) {
   205       if (selected_token.needsLogin() || !(selected_token.needsUserInit)) {
   206         pw_toggle = "false";
   207         if(selected_token.needsLogin()) {
   208           if (selected_token.isLoggedIn()) {
   209             logout_toggle = "false";
   210           } else {
   211             login_toggle = "false";
   212           }
   213         }
   214       }
   215     }
   216     showSlotInfo();
   217   }
   218   var thebutton = document.getElementById('login_button');
   219   thebutton.setAttribute("disabled", login_toggle);
   220   thebutton = document.getElementById('logout_button');
   221   thebutton.setAttribute("disabled", logout_toggle);
   222   thebutton = document.getElementById('change_pw_button');
   223   thebutton.setAttribute("disabled", pw_toggle);
   224   thebutton = document.getElementById('unload_button');
   225   thebutton.setAttribute("disabled", unload_toggle);
   226   // not implemented
   227   //thebutton = document.getElementById('change_slotname_button');
   228   //thebutton.setAttribute("disabled", toggle);
   229 }
   231 // clear the display of information for the slot
   232 function ClearInfoList()
   233 {
   234   var info_list = document.getElementById("info_list");
   235   while (info_list.firstChild)
   236       info_list.removeChild(info_list.firstChild);
   237 }
   239 function ClearDeviceList()
   240 {
   241   ClearInfoList();
   243   skip_enable_buttons = true;
   244   var tree = document.getElementById('device_tree');
   245   tree.view.selection.clearSelection();
   246   skip_enable_buttons = false;
   248   // Remove the existing listed modules so that refresh doesn't 
   249   // display the module that just changed.
   250   var device_list = document.getElementById("device_list");
   251   while (device_list.hasChildNodes())
   252     device_list.removeChild(device_list.firstChild);
   253 }
   256 // show a list of info about a slot
   257 function showSlotInfo()
   258 {
   259   var present = true;
   260   ClearInfoList();
   261   switch (selected_slot.status) {
   262    case nsIPKCS11Slot.SLOT_DISABLED:
   263      AddInfoRow(bundle.getString("devinfo_status"),
   264                 bundle.getString("devinfo_stat_disabled"),
   265                 "tok_status");
   266      present = false;
   267      break;
   268    case nsIPKCS11Slot.SLOT_NOT_PRESENT:
   269      AddInfoRow(bundle.getString("devinfo_status"),
   270                 bundle.getString("devinfo_stat_notpresent"),
   271                 "tok_status");
   272      present = false;
   273      break;
   274    case nsIPKCS11Slot.SLOT_UNINITIALIZED:
   275      AddInfoRow(bundle.getString("devinfo_status"),
   276                 bundle.getString("devinfo_stat_uninitialized"),
   277                 "tok_status");
   278      break;
   279    case nsIPKCS11Slot.SLOT_NOT_LOGGED_IN:
   280      AddInfoRow(bundle.getString("devinfo_status"),
   281                 bundle.getString("devinfo_stat_notloggedin"),
   282                 "tok_status");
   283      break;
   284    case nsIPKCS11Slot.SLOT_LOGGED_IN:
   285      AddInfoRow(bundle.getString("devinfo_status"),
   286                 bundle.getString("devinfo_stat_loggedin"),
   287                 "tok_status");
   288      break;
   289    case nsIPKCS11Slot.SLOT_READY:
   290      AddInfoRow(bundle.getString("devinfo_status"),
   291                 bundle.getString("devinfo_stat_ready"),
   292                 "tok_status");
   293      break;
   294   }
   295   AddInfoRow(bundle.getString("devinfo_desc"),
   296              selected_slot.desc, "slot_desc");
   297   AddInfoRow(bundle.getString("devinfo_manID"),
   298              selected_slot.manID, "slot_manID");
   299   AddInfoRow(bundle.getString("devinfo_hwversion"),
   300              selected_slot.HWVersion, "slot_hwv");
   301   AddInfoRow(bundle.getString("devinfo_fwversion"),
   302              selected_slot.FWVersion, "slot_fwv");
   303   if (present) {
   304      showTokenInfo();
   305   }
   306 }
   308 function showModuleInfo()
   309 {
   310   ClearInfoList();
   311   AddInfoRow(bundle.getString("devinfo_modname"),
   312              selected_module.name, "module_name");
   313   AddInfoRow(bundle.getString("devinfo_modpath"),
   314              selected_module.libName, "module_path");
   315 }
   317 // add a row to the info list, as [col1 col2] (ex.: ["status" "logged in"])
   318 function AddInfoRow(col1, col2, cell_id)
   319 {
   320   var tree = document.getElementById("info_list");
   321   var item  = document.createElement("treeitem");
   322   var row  = document.createElement("treerow");
   323   var cell1 = document.createElement("treecell");
   324   cell1.setAttribute("label", col1);
   325   cell1.setAttribute("crop", "never");
   326   row.appendChild(cell1);
   327   var cell2 = document.createElement("treecell");
   328   cell2.setAttribute("label", col2);
   329   cell2.setAttribute("crop", "never");
   330   cell2.setAttribute("id", cell_id);
   331   row.appendChild(cell2);
   332   item.appendChild(row);
   333   tree.appendChild(item);
   334 }
   336 // log in to a slot
   337 function doLogin()
   338 {
   339   getSelectedItem();
   340   // here's the workaround - login functions are with token
   341   var selected_token = selected_slot.getToken();
   342   try {
   343     selected_token.login(false);
   344     var tok_status = document.getElementById("tok_status");
   345     if (selected_token.isLoggedIn()) {
   346       tok_status.setAttribute("label", 
   347                               bundle.getString("devinfo_stat_loggedin"));
   348     } else {
   349       tok_status.setAttribute("label",
   350                               bundle.getString("devinfo_stat_notloggedin"));
   351     }
   352   } catch (e) {
   353     doPrompt(bundle.getString("login_failed"));
   354   }
   355   enableButtons();
   356 }
   358 // log out of a slot
   359 function doLogout()
   360 {
   361   getSelectedItem();
   362   // here's the workaround - login functions are with token
   363   var selected_token = selected_slot.getToken();
   364   try {
   365     selected_token.logoutAndDropAuthenticatedResources();
   366     var tok_status = document.getElementById("tok_status");
   367     if (selected_token.isLoggedIn()) {
   368       tok_status.setAttribute("label", 
   369                               bundle.getString("devinfo_stat_loggedin"));
   370     } else {
   371       tok_status.setAttribute("label",
   372                               bundle.getString("devinfo_stat_notloggedin"));
   373     }
   374   } catch (e) {
   375   }
   376   enableButtons();
   377 }
   379 // load a new device
   380 function doLoad()
   381 {
   382   window.open("load_device.xul", "loaddevice", 
   383               "chrome,centerscreen,modal");
   384   ClearDeviceList();
   385   RefreshDeviceList();
   386 }
   388 function deleteSelected()
   389 {
   390   getSelectedItem();
   391   if (selected_module &&
   392       doConfirm(getNSSString("DelModuleWarning"))) {
   393     try {
   394       getPKCS11().deleteModule(selected_module.name);
   395     }
   396     catch (e) {
   397       doPrompt(getNSSString("DelModuleError"));
   398       return false;
   399     }
   400     selected_module = null;
   401     return true;
   402   }
   403   return false;
   404 }
   406 function doUnload()
   407 {
   408   if (deleteSelected()) {
   409     ClearDeviceList();
   410     RefreshDeviceList();
   411   }
   412 }
   414 // handle card insertion and removal
   415 function onSmartCardChange()
   416 {
   417   var tree = document.getElementById('device_tree');
   418   var index = tree.currentIndex;
   419   tree.currentIndex = 0;
   420   ClearDeviceList();
   421   RefreshDeviceList();
   422   tree.currentIndex = index;
   423   enableButtons();
   424 }
   426 function changePassword()
   427 {
   428   getSelectedItem();
   429   var params = Components.classes[nsDialogParamBlock].createInstance(nsIDialogParamBlock);
   430   params.SetString(1,selected_slot.tokenName);
   431   window.openDialog("changepassword.xul",
   432               "", 
   433               "chrome,centerscreen,modal", params);
   434   showSlotInfo();
   435   enableButtons();
   436 }
   438 // browse fs for PKCS#11 device
   439 function doBrowseFiles()
   440 {
   441   var srbundle = document.getElementById("pippki_bundle");
   442   var fp = Components.classes[nsFilePicker].createInstance(nsIFilePicker);
   443   fp.init(window,
   444           srbundle.getString("loadPK11TokenDialog"),
   445           nsIFilePicker.modeOpen);
   446   fp.appendFilters(nsIFilePicker.filterAll);
   447   if (fp.show() == nsIFilePicker.returnOK) {
   448     var pathbox = document.getElementById("device_path");
   449     pathbox.setAttribute("value", fp.file.path);
   450   }
   451 }
   453 function doLoadDevice()
   454 {
   455   var name_box = document.getElementById("device_name");
   456   var path_box = document.getElementById("device_path");
   457   try {
   458     getPKCS11().addModule(name_box.value, path_box.value, 0,0);
   459   }
   460   catch (e) {
   461     if (e.result == Components.results.NS_ERROR_ILLEGAL_VALUE)
   462       doPrompt(getNSSString("AddModuleDup"));
   463     else
   464       doPrompt(getNSSString("AddModuleFailure"));
   466     return false;
   467   }
   468   return true;
   469 }
   471 // -------------------------------------   Old code
   473 function showTokenInfo()
   474 {
   475   //ClearInfoList();
   476   var selected_token = selected_slot.getToken();
   477   AddInfoRow(bundle.getString("devinfo_label"),
   478              selected_token.tokenLabel, "tok_label");
   479   AddInfoRow(bundle.getString("devinfo_manID"),
   480              selected_token.tokenManID, "tok_manID");
   481   AddInfoRow(bundle.getString("devinfo_serialnum"),
   482              selected_token.tokenSerialNumber, "tok_sNum");
   483   AddInfoRow(bundle.getString("devinfo_hwversion"),
   484              selected_token.tokenHWVersion, "tok_hwv");
   485   AddInfoRow(bundle.getString("devinfo_fwversion"),
   486              selected_token.tokenFWVersion, "tok_fwv");
   487 }
   489 function toggleFIPS()
   490 {
   491   if (!secmoddb.isFIPSEnabled) {
   492     // A restriction of FIPS mode is, the password must be set
   493     // In FIPS mode the password must be non-empty.
   494     // This is different from what we allow in NON-Fips mode.
   496     var tokendb = Components.classes[nsPK11TokenDB].getService(nsIPK11TokenDB);
   497     var internal_token = tokendb.getInternalKeyToken(); // nsIPK11Token
   498     var slot = secmoddb.findSlotByName(internal_token.tokenName);
   499     switch (slot.status) {
   500       case nsIPKCS11Slot.SLOT_UNINITIALIZED:
   501       case nsIPKCS11Slot.SLOT_READY:
   502         // Token has either no or an empty password.
   503         doPrompt(bundle.getString("fips_nonempty_password_required"));
   504         return;
   505     }
   506   }
   508   try {
   509     secmoddb.toggleFIPSMode();
   510   }
   511   catch (e) {
   512     doPrompt(bundle.getString("unable_to_toggle_FIPS"));
   513     return;
   514   }
   516   //Remove the existing listed modules so that re-fresh doesn't 
   517   //display the module that just changed.
   518   ClearDeviceList();
   520   RefreshDeviceList();
   521 }

mercurial