home *** CD-ROM | disk | FTP | other *** search
/ PC World 2003 May / PCWorld_2003-05_cd.bin / Komunik / phoenix / chrome / pippki.jar / content / pippki / device_manager.js < prev    next >
Text File  |  2002-08-23  |  15KB  |  440 lines

  1.  /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  *
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  *
  12.  * The Original Code is mozilla.org code.
  13.  *
  14.  * The Initial Developer of the Original Code is Netscape
  15.  * Communications Corporation.  Portions created by Netscape are
  16.  * Copyright (C) 2001 Netscape Communications Corporation. All
  17.  * Rights Reserved.
  18.  *
  19.  * Contributor(s):
  20.  *  Bob Lord <lord@netscape.com>
  21.  *  Ian McGreer <mcgreer@netscape.com>
  22.  */
  23.  
  24. const nsIFilePicker = Components.interfaces.nsIFilePicker;
  25. const nsFilePicker = "@mozilla.org/filepicker;1";
  26. const nsIPKCS11Slot = Components.interfaces.nsIPKCS11Slot;
  27. const nsIPKCS11Module = Components.interfaces.nsIPKCS11Module;
  28. const nsPKCS11ModuleDB = "@mozilla.org/security/pkcs11moduledb;1";
  29. const nsIPKCS11ModuleDB = Components.interfaces.nsIPKCS11ModuleDB;
  30. const nsIPK11Token = Components.interfaces.nsIPK11Token;
  31. const nsPK11TokenDB = "@mozilla.org/security/pk11tokendb;1";
  32. const nsIPK11TokenDB = Components.interfaces.nsIPK11TokenDB;
  33. const nsIDialogParamBlock = Components.interfaces.nsIDialogParamBlock;
  34. const nsDialogParamBlock = "@mozilla.org/embedcomp/dialogparam;1";
  35.  
  36. var bundle;
  37. var secmoddb;
  38.  
  39. /* Do the initial load of all PKCS# modules and list them. */
  40. function LoadModules()
  41. {
  42.   bundle = srGetStrBundle("chrome://pippki/locale/pippki.properties");
  43.   secmoddb = Components.classes[nsPKCS11ModuleDB].getService(nsIPKCS11ModuleDB);
  44.   var modules = secmoddb.listModules();
  45.   var done = false;
  46.   try {
  47.     modules.isDone();
  48.   } catch (e) { done = true; }
  49.   while (!done) {
  50.     var module = modules.currentItem().QueryInterface(nsIPKCS11Module);
  51.     if (module) {
  52.       var slotnames = [];
  53.       var slots = module.listSlots();
  54.       var slots_done = false;
  55.       try {
  56.         slots.isDone();
  57.       } catch (e) { slots_done = true; }
  58.       while (!slots_done) {
  59.         var slot = null;
  60.      try {
  61.           slot = slots.currentItem().QueryInterface(nsIPKCS11Slot);
  62.         } catch (e) { slot = null; }
  63.         // in the ongoing discussion of whether slot names or token names
  64.         // are to be shown, I've gone with token names because NSS will
  65.         // prefer lookup by token name.  However, the token may not be
  66.         // present, so maybe slot names should be listed, while token names
  67.         // are "remembered" for lookup?
  68.     if (slot != null) {
  69.           if (slot.tokenName)
  70.             slotnames[slotnames.length] = slot.tokenName;
  71.           else
  72.             slotnames[slotnames.length] = slot.name;
  73.     }
  74.         try {
  75.           slots.next();
  76.         } catch (e) { slots_done = true; }
  77.       }
  78.       AddModule(module.name, slotnames);
  79.     }
  80.     try {
  81.       modules.next();
  82.     } catch (e) { done = true; }
  83.   }
  84.   /* Set the text on the fips button */
  85.   SetFIPSButton();
  86. }
  87.  
  88. function SetFIPSButton()
  89. {
  90.   var fipsButton = document.getElementById("fipsbutton");
  91.   var label;
  92.   if (secmoddb.isFIPSEnabled) {
  93.    label = bundle.GetStringFromName("disable_fips"); 
  94.   } else {
  95.    label = bundle.GetStringFromName("enable_fips"); 
  96.   }
  97.   fipsButton.setAttribute("label", label);
  98.  
  99.   var can_toggle = secmoddb.canToggleFIPS;
  100.   if (can_toggle) {
  101.     fipsButton.removeAttribute("disabled");
  102.   } else {
  103.     fipsButton.setAttribute("disabled", "true");
  104.   }
  105. }
  106.  
  107. /* Add a module to the tree.  slots is the array of slots in the module,
  108.  * to be represented as children.
  109.  */
  110. function AddModule(module, slots)
  111. {
  112.   var tree = document.getElementById("device_list");
  113.   var item  = document.createElement("treeitem");
  114.   var row  = document.createElement("treerow");
  115.   var cell = document.createElement("treecell");
  116.   cell.setAttribute("label", module);
  117.   row.appendChild(cell);
  118.   item.appendChild(row);
  119.   var parent = document.createElement("treechildren");
  120.   for (var i = 0; i<slots.length; i++) {
  121.     var child_item = document.createElement("treeitem");
  122.     var child_row = document.createElement("treerow");
  123.     var child_cell = document.createElement("treecell");
  124.     child_cell.setAttribute("label", slots[i]);
  125.     child_row.appendChild(child_cell);
  126.     child_item.appendChild(child_row);
  127.     child_item.setAttribute("pk11kind", "slot");
  128.     parent.appendChild(child_item);
  129.   }
  130.   item.appendChild(parent);
  131.   item.setAttribute("pk11kind", "module");
  132.   item.setAttribute("open", "true");
  133.   item.setAttribute("container", "true");
  134.   tree.appendChild(item);
  135. }
  136.  
  137. var selected_slot;
  138. var selected_module;
  139.  
  140. /* get the slot selected by the user (can only be one-at-a-time) */
  141. function getSelectedItem()
  142. {
  143.   var tree = document.getElementById('device_tree');
  144.   if (tree.currentIndex < 0) return;
  145.   var item = tree.contentView.getItemAtIndex(tree.currentIndex);
  146.   selected_slot = null;
  147.   selected_module = null;
  148.   if (item) {
  149.     var kind = item.getAttribute("pk11kind");
  150.     var module_name;
  151.     if (kind == "slot") {
  152.       // get the module cell for this slot cell
  153.       var cell = item.parentNode.parentNode.firstChild.firstChild;
  154.       module_name = cell.getAttribute("label");
  155.       var module = secmoddb.findModuleByName(module_name);
  156.       // get the cell for the selected row (the slot to display)
  157.       cell = item.firstChild.firstChild;
  158.       var slot_name = cell.getAttribute("label");
  159.       selected_slot = module.findSlotByName(slot_name);
  160.     } else { // (kind == "module")
  161.       // get the cell for the selected row (the module to display)
  162.       cell = item.firstChild.firstChild;
  163.       module_name = cell.getAttribute("label");
  164.       selected_module = secmoddb.findModuleByName(module_name);
  165.     }
  166.   }
  167. }
  168.  
  169. function enableButtons()
  170. {
  171.   var login_toggle = "true";
  172.   var logout_toggle = "true";
  173.   var pw_toggle = "true";
  174.   var unload_toggle = "true";
  175.   getSelectedItem();
  176.   if (selected_module) {
  177.     unload_toggle = "false";
  178.     showModuleInfo();
  179.   } else if (selected_slot) {
  180.     // here's the workaround - login functions are all with token,
  181.     // so grab the token type
  182.     var selected_token = selected_slot.getToken();
  183.     if (selected_token != null) {
  184.       if (selected_token.needsLogin() || !(selected_token.needsUserInit)) {
  185.         pw_toggle = "false";
  186.         if(selected_token.needsLogin()) {
  187.           if (selected_token.isLoggedIn()) {
  188.             logout_toggle = "false";
  189.           } else {
  190.             login_toggle = "false";
  191.           }
  192.         }
  193.       }
  194.     }
  195.     showSlotInfo();
  196.   }
  197.   var thebutton = document.getElementById('login_button');
  198.   thebutton.setAttribute("disabled", login_toggle);
  199.   thebutton = document.getElementById('logout_button');
  200.   thebutton.setAttribute("disabled", logout_toggle);
  201.   thebutton = document.getElementById('change_pw_button');
  202.   thebutton.setAttribute("disabled", pw_toggle);
  203.   thebutton = document.getElementById('unload_button');
  204.   thebutton.setAttribute("disabled", unload_toggle);
  205.   // not implemented
  206.   //thebutton = document.getElementById('change_slotname_button');
  207.   //thebutton.setAttribute("disabled", toggle);
  208. }
  209.  
  210. // clear the display of information for the slot
  211. function ClearInfoList()
  212. {
  213.   var info_list = document.getElementById("info_list");
  214.   while (info_list.firstChild)
  215.       info_list.removeChild(info_list.firstChild);
  216. }
  217.  
  218. // show a list of info about a slot
  219. function showSlotInfo()
  220. {
  221.   ClearInfoList();
  222.   switch (selected_slot.status) {
  223.    case nsIPKCS11Slot.SLOT_DISABLED:
  224.      AddInfoRow(bundle.GetStringFromName("devinfo_status"), 
  225.                 bundle.GetStringFromName("devinfo_stat_disabled"), 
  226.                 "tok_status");
  227.      break;
  228.    case nsIPKCS11Slot.SLOT_NOT_PRESENT:
  229.      AddInfoRow(bundle.GetStringFromName("devinfo_status"), 
  230.                 bundle.GetStringFromName("devinfo_stat_notpresent"), 
  231.                 "tok_status");
  232.      break;
  233.    case nsIPKCS11Slot.SLOT_UNINITIALIZED:
  234.      AddInfoRow(bundle.GetStringFromName("devinfo_status"), 
  235.                 bundle.GetStringFromName("devinfo_stat_uninitialized"), 
  236.                 "tok_status");
  237.      break;
  238.    case nsIPKCS11Slot.SLOT_NOT_LOGGED_IN:
  239.      AddInfoRow(bundle.GetStringFromName("devinfo_status"), 
  240.                 bundle.GetStringFromName("devinfo_stat_notloggedin"), 
  241.                 "tok_status");
  242.      break;
  243.    case nsIPKCS11Slot.SLOT_LOGGED_IN:
  244.      AddInfoRow(bundle.GetStringFromName("devinfo_status"), 
  245.                 bundle.GetStringFromName("devinfo_stat_loggedin"), 
  246.                 "tok_status");
  247.      break;
  248.    case nsIPKCS11Slot.SLOT_READY:
  249.      AddInfoRow(bundle.GetStringFromName("devinfo_status"), 
  250.                 bundle.GetStringFromName("devinfo_stat_ready"), 
  251.                 "tok_status");
  252.      break;
  253.   }
  254.   AddInfoRow(bundle.GetStringFromName("devinfo_desc"), 
  255.              selected_slot.desc, "slot_desc");
  256.   AddInfoRow(bundle.GetStringFromName("devinfo_manID"), 
  257.              selected_slot.manID, "slot_manID");
  258.   AddInfoRow(bundle.GetStringFromName("devinfo_hwversion"),
  259.              selected_slot.HWVersion, "slot_hwv");
  260.   AddInfoRow(bundle.GetStringFromName("devinfo_fwversion"),
  261.              selected_slot.FWVersion, "slot_fwv");
  262. }
  263.  
  264. function showModuleInfo()
  265. {
  266.   ClearInfoList();
  267.   AddInfoRow(bundle.GetStringFromName("devinfo_modname"),
  268.              selected_module.name, "module_name");
  269.   AddInfoRow(bundle.GetStringFromName("devinfo_modpath"),
  270.              selected_module.libName, "module_path");
  271. }
  272.  
  273. // add a row to the info list, as [col1 col2] (ex.: ["status" "logged in"])
  274. function AddInfoRow(col1, col2, cell_id)
  275. {
  276.   var tree = document.getElementById("info_list");
  277.   var item  = document.createElement("treeitem");
  278.   var row  = document.createElement("treerow");
  279.   var cell1 = document.createElement("treecell");
  280.   cell1.setAttribute("label", col1);
  281.   cell1.setAttribute("crop", "never");
  282.   row.appendChild(cell1);
  283.   var cell2 = document.createElement("treecell");
  284.   cell2.setAttribute("label", col2);
  285.   cell2.setAttribute("crop", "never");
  286.   cell2.setAttribute("id", cell_id);
  287.   row.appendChild(cell2);
  288.   item.appendChild(row);
  289.   tree.appendChild(item);
  290. }
  291.  
  292. // log in to a slot
  293. function doLogin()
  294. {
  295.   getSelectedItem();
  296.   // here's the workaround - login functions are with token
  297.   var selected_token = selected_slot.getToken();
  298.   try {
  299.     selected_token.login(false);
  300.     var tok_status = document.getElementById("tok_status");
  301.     if (selected_token.isLoggedIn()) {
  302.       tok_status.setAttribute("label", 
  303.                           bundle.GetStringFromName("devinfo_stat_loggedin"));
  304.     } else {
  305.       tok_status.setAttribute("label",
  306.                        bundle.GetStringFromName("devinfo_stat_notloggedin"));
  307.     }
  308.   } catch (e) {
  309.     var alertStr = bundle.GetStringFromName("login_failed"); 
  310.     alert(alertStr);
  311.   }
  312.   enableButtons();
  313. }
  314.  
  315. // log out of a slot
  316. function doLogout()
  317. {
  318.   getSelectedItem();
  319.   // here's the workaround - login functions are with token
  320.   var selected_token = selected_slot.getToken();
  321.   try {
  322.     selected_token.logout(false);
  323.     var tok_status = document.getElementById("tok_status");
  324.     if (selected_token.isLoggedIn()) {
  325.       tok_status.setAttribute("label", 
  326.                           bundle.GetStringFromName("devinfo_stat_loggedin"));
  327.     } else {
  328.       tok_status.setAttribute("label",
  329.                        bundle.GetStringFromName("devinfo_stat_notloggedin"));
  330.     }
  331.   } catch (e) {
  332.   }
  333.   enableButtons();
  334. }
  335.  
  336. // load a new device
  337. function doLoad()
  338. {
  339.   window.open("load_device.xul", "loaddevice", 
  340.               "chrome,resizable=1,dialog=1,modal=1");
  341.   var device_list = document.getElementById("device_list");
  342.   while (device_list.firstChild)
  343.     device_list.removeChild(device_list.firstChild);
  344.   LoadModules();
  345. }
  346.  
  347. function doUnload()
  348. {
  349.   getSelectedItem();
  350.   if (selected_module) {
  351.     pkcs11.deletemodule(selected_module.name);
  352.     var device_list = document.getElementById("device_list");
  353.     while (device_list.firstChild)
  354.       device_list.removeChild(device_list.firstChild);
  355.     LoadModules();
  356.   }
  357. }
  358.  
  359. function changePassword()
  360. {
  361.   getSelectedItem();
  362.   var params = Components.classes[nsDialogParamBlock].createInstance(nsIDialogParamBlock);
  363.   params.SetString(1,selected_slot.tokenName);
  364.   window.openDialog("changepassword.xul",
  365.               "", 
  366.               "chrome,resizable=1,modal=1,dialog=1",params);
  367.   showSlotInfo();
  368.   enableButtons();
  369. }
  370.  
  371. // browse fs for PKCS#11 device
  372. function doBrowseFiles()
  373. {
  374.   var srbundle = srGetStrBundle("chrome://pippki/locale/pippki.properties");
  375.   var fp = Components.classes[nsFilePicker].createInstance(nsIFilePicker);
  376.   fp.init(window,
  377.           srbundle.GetStringFromName("loadPK11TokenDialog"),
  378.           nsIFilePicker.modeOpen);
  379.   fp.appendFilters(nsIFilePicker.filterAll);
  380.   if (fp.show() == nsIFilePicker.returnOK) {
  381.     var pathbox = document.getElementById("device_path");
  382.     pathbox.setAttribute("value", fp.file.persistentDescriptor);
  383.   }
  384. }
  385.  
  386. function doLoadDevice()
  387. {
  388.   var name_box = document.getElementById("device_name");
  389.   var path_box = document.getElementById("device_path");
  390.   pkcs11.addmodule(name_box.value, path_box.value, 0,0);
  391.   window.close();
  392. }
  393.  
  394. // -------------------------------------   Old code
  395.  
  396. function showTokenInfo()
  397. {
  398.   ClearInfoList();
  399.   getSelectedToken();
  400.   AddInfoRow(bundle.GetStringFromName("devinfo_label"), 
  401.              selected_token.tokenLabel, "tok_label");
  402.   AddInfoRow(bundle.GetStringFromName("devinfo_manID"),
  403.              selected_token.tokenManID, "tok_manID");
  404.   AddInfoRow(bundle.GetStringFromName("devinfo_serialnum"), 
  405.              selected_token.tokenSerialNumber, "tok_sNum");
  406.   AddInfoRow(bundle.GetStringFromName("devinfo_hwversion"),
  407.              selected_token.tokenHWVersion, "tok_hwv");
  408.   AddInfoRow(bundle.GetStringFromName("devinfo_fwversion"),
  409.              selected_token.tokenFWVersion, "tok_fwv");
  410. }
  411.  
  412. function toggleFIPS()
  413. {
  414.   if (!secmoddb.isFIPSEnabled) {
  415.     // A restriction of FIPS mode is, the password must be set
  416.     // In FIPS mode the password must be non-empty.
  417.     // This is different from what we allow in NON-Fips mode.
  418.  
  419.     var tokendb = Components.classes[nsPK11TokenDB].getService(nsIPK11TokenDB);
  420.     var internal_token = tokendb.getInternalKeyToken(); // nsIPK11Token
  421.     var slot = secmoddb.findSlotByName(internal_token.tokenName);
  422.     switch (slot.status) {
  423.       case nsIPKCS11Slot.SLOT_UNINITIALIZED:
  424.       case nsIPKCS11Slot.SLOT_READY:
  425.         // Token has either no or an empty password.
  426.         alert(bundle.GetStringFromName("fips_nonempty_password_required"));
  427.         return;
  428.     }
  429.   }
  430.   
  431.   secmoddb.toggleFIPSMode();
  432.   //Remove the existing listed modules so that re-fresh doesn't 
  433.   //display the module that just changed.
  434.   var device_list = document.getElementById("device_list");
  435.   while (device_list.firstChild)
  436.     device_list.removeChild(device_list.firstChild);
  437.  
  438.   LoadModules();
  439. }
  440.