no bug - Import translations from android-l10n r=release a=l10n CLOSED TREE
[gecko.git] / security / manager / pki / resources / content / device_manager.js
blobdeb58d2ff3b4db5d8199b45d76c970859293d520
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";
6 const { XPCOMUtils } = ChromeUtils.importESModule(
7   "resource://gre/modules/XPCOMUtils.sys.mjs"
8 );
10 var secmoddb;
11 var skip_enable_buttons = false;
13 /* Do the initial load of all PKCS# modules and list them. */
14 function LoadModules() {
15   secmoddb = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService(
16     Ci.nsIPKCS11ModuleDB
17   );
18   RefreshDeviceList();
21 async function doPrompt(l10n_id) {
22   let [msg] = await document.l10n.formatValues([{ id: l10n_id }]);
23   Services.prompt.alert(window, null, msg);
26 async function doConfirm(l10n_id) {
27   let [msg] = await document.l10n.formatValues([{ id: l10n_id }]);
28   return Services.prompt.confirm(window, null, msg);
31 function RefreshDeviceList() {
32   for (let module of secmoddb.listModules()) {
33     let slots = module.listSlots();
34     AddModule(module, slots);
35   }
37   // Set the text on the FIPS button.
38   SetFIPSButton();
41 function SetFIPSButton() {
42   var fipsButton = document.getElementById("fipsbutton");
43   if (secmoddb.isFIPSEnabled) {
44     document.l10n.setAttributes(fipsButton, "devmgr-button-disable-fips");
45   } else {
46     document.l10n.setAttributes(fipsButton, "devmgr-button-enable-fips");
47   }
49   var can_toggle = secmoddb.canToggleFIPS;
50   if (can_toggle) {
51     fipsButton.removeAttribute("disabled");
52   } else {
53     fipsButton.setAttribute("disabled", "true");
54   }
57 /* Add a module to the tree.  slots is the array of slots in the module,
58  * to be represented as children.
59  */
60 function AddModule(module, slots) {
61   var tree = document.getElementById("device_list");
62   var item = document.createXULElement("treeitem");
63   var row = document.createXULElement("treerow");
64   var cell = document.createXULElement("treecell");
65   cell.setAttribute("label", module.name);
66   row.appendChild(cell);
67   item.appendChild(row);
68   var parent = document.createXULElement("treechildren");
69   for (let slot of slots) {
70     var child_item = document.createXULElement("treeitem");
71     var child_row = document.createXULElement("treerow");
72     var child_cell = document.createXULElement("treecell");
73     child_cell.setAttribute("label", slot.name);
74     child_row.appendChild(child_cell);
75     child_item.appendChild(child_row);
76     child_item.setAttribute("pk11kind", "slot");
77     // 'slot' is an attribute on any HTML element, hence 'slotObject' instead.
78     child_item.slotObject = slot;
79     parent.appendChild(child_item);
80   }
81   item.appendChild(parent);
82   item.setAttribute("pk11kind", "module");
83   item.module = module;
84   item.setAttribute("open", "true");
85   item.setAttribute("container", "true");
86   tree.appendChild(item);
89 var selected_slot;
90 var selected_module;
92 /* get the slot selected by the user (can only be one-at-a-time) */
93 function getSelectedItem() {
94   let tree = document.getElementById("device_tree");
95   if (tree.currentIndex < 0) {
96     return;
97   }
98   let item = tree.view.getItemAtIndex(tree.currentIndex);
99   selected_slot = null;
100   selected_module = null;
101   if (item) {
102     let kind = item.getAttribute("pk11kind");
103     if (kind == "slot") {
104       selected_slot = item.slotObject;
105     } else {
106       // (kind == "module")
107       selected_module = item.module;
108     }
109   }
112 function enableButtons() {
113   if (skip_enable_buttons) {
114     return;
115   }
117   var login_toggle = "true";
118   var logout_toggle = "true";
119   var pw_toggle = "true";
120   var unload_toggle = "true";
121   getSelectedItem();
122   if (selected_module) {
123     unload_toggle = "false";
124     showModuleInfo();
125   } else if (selected_slot) {
126     // here's the workaround - login functions are all with token,
127     // so grab the token type
128     var selected_token = selected_slot.getToken();
129     if (selected_token != null) {
130       if (selected_token.needsLogin() || !selected_token.needsUserInit) {
131         pw_toggle = "false";
132         if (selected_token.needsLogin()) {
133           if (selected_token.isLoggedIn()) {
134             logout_toggle = "false";
135           } else {
136             login_toggle = "false";
137           }
138         }
139       }
141       if (
142         !Services.policies.isAllowed("createMasterPassword") &&
143         selected_token.isInternalKeyToken &&
144         !selected_token.hasPassword
145       ) {
146         pw_toggle = "true";
147       }
148     }
149     showSlotInfo();
150   }
151   document
152     .getElementById("login_button")
153     .setAttribute("disabled", login_toggle);
154   document
155     .getElementById("logout_button")
156     .setAttribute("disabled", logout_toggle);
157   document
158     .getElementById("change_pw_button")
159     .setAttribute("disabled", pw_toggle);
160   document
161     .getElementById("unload_button")
162     .setAttribute("disabled", unload_toggle);
165 // clear the display of information for the slot
166 function ClearInfoList() {
167   let infoList = document.getElementById("info_list");
168   while (infoList.hasChildNodes()) {
169     infoList.firstChild.remove();
170   }
173 function ClearDeviceList() {
174   ClearInfoList();
176   skip_enable_buttons = true;
177   var tree = document.getElementById("device_tree");
178   tree.view.selection.clearSelection();
179   skip_enable_buttons = false;
181   // Remove the existing listed modules so that a refresh doesn't display the
182   // module that just changed.
183   let deviceList = document.getElementById("device_list");
184   while (deviceList.hasChildNodes()) {
185     deviceList.firstChild.remove();
186   }
189 // show a list of info about a slot
190 function showSlotInfo() {
191   var present = true;
192   ClearInfoList();
193   switch (selected_slot.status) {
194     case Ci.nsIPKCS11Slot.SLOT_DISABLED:
195       AddInfoRow(
196         "devinfo-status",
197         { l10nID: "devinfo-status-disabled" },
198         "tok_status"
199       );
200       present = false;
201       break;
202     case Ci.nsIPKCS11Slot.SLOT_NOT_PRESENT:
203       AddInfoRow(
204         "devinfo-status",
205         { l10nID: "devinfo-status-not-present" },
206         "tok_status"
207       );
208       present = false;
209       break;
210     case Ci.nsIPKCS11Slot.SLOT_UNINITIALIZED:
211       AddInfoRow(
212         "devinfo-status",
213         { l10nID: "devinfo-status-uninitialized" },
214         "tok_status"
215       );
216       break;
217     case Ci.nsIPKCS11Slot.SLOT_NOT_LOGGED_IN:
218       AddInfoRow(
219         "devinfo-status",
220         { l10nID: "devinfo-status-not-logged-in" },
221         "tok_status"
222       );
223       break;
224     case Ci.nsIPKCS11Slot.SLOT_LOGGED_IN:
225       AddInfoRow(
226         "devinfo-status",
227         { l10nID: "devinfo-status-logged-in" },
228         "tok_status"
229       );
230       break;
231     case Ci.nsIPKCS11Slot.SLOT_READY:
232       AddInfoRow(
233         "devinfo-status",
234         { l10nID: "devinfo-status-ready" },
235         "tok_status"
236       );
237       break;
238     default:
239       return;
240   }
241   AddInfoRow("devinfo-desc", { label: selected_slot.desc }, "slot_desc");
242   AddInfoRow("devinfo-man-id", { label: selected_slot.manID }, "slot_manID");
243   AddInfoRow(
244     "devinfo-hwversion",
245     { label: selected_slot.HWVersion },
246     "slot_hwv"
247   );
248   AddInfoRow(
249     "devinfo-fwversion",
250     { label: selected_slot.FWVersion },
251     "slot_fwv"
252   );
253   if (present) {
254     showTokenInfo();
255   }
258 function showModuleInfo() {
259   ClearInfoList();
260   AddInfoRow("devinfo-modname", { label: selected_module.name }, "module_name");
261   AddInfoRow(
262     "devinfo-modpath",
263     { label: selected_module.libName },
264     "module_path"
265   );
268 // add a row to the info list, as [col1 col2] (ex.: ["status" "logged in"])
269 function AddInfoRow(l10nID, col2, cell_id) {
270   var tree = document.getElementById("info_list");
271   var item = document.createXULElement("treeitem");
272   var row = document.createXULElement("treerow");
273   var cell1 = document.createXULElement("treecell");
274   document.l10n.setAttributes(cell1, l10nID);
275   cell1.setAttribute("crop", "never");
276   row.appendChild(cell1);
277   var cell2 = document.createXULElement("treecell");
278   if (col2.l10nID) {
279     document.l10n.setAttributes(cell2, col2.l10nID);
280   } else {
281     cell2.setAttribute("label", col2.label);
282   }
283   cell2.setAttribute("crop", "never");
284   cell2.setAttribute("id", cell_id);
285   row.appendChild(cell2);
286   item.appendChild(row);
287   tree.appendChild(item);
290 // log in to a slot
291 function doLogin() {
292   getSelectedItem();
293   // here's the workaround - login functions are with token
294   var selected_token = selected_slot.getToken();
295   try {
296     selected_token.login(false);
297     var tok_status = document.getElementById("tok_status");
298     if (selected_token.isLoggedIn()) {
299       document.l10n.setAttributes(tok_status, "devinfo-status-logged-in");
300     } else {
301       document.l10n.setAttributes(tok_status, "devinfo-status-not-logged-in");
302     }
303   } catch (e) {
304     doPrompt("login-failed");
305   }
306   enableButtons();
309 // log out of a slot
310 function doLogout() {
311   getSelectedItem();
312   // here's the workaround - login functions are with token
313   var selected_token = selected_slot.getToken();
314   try {
315     selected_token.logoutAndDropAuthenticatedResources();
316     var tok_status = document.getElementById("tok_status");
317     if (selected_token.isLoggedIn()) {
318       document.l10n.setAttributes(tok_status, "devinfo-status-logged-in");
319     } else {
320       document.l10n.setAttributes(tok_status, "devinfo-status-not-logged-in");
321     }
322   } catch (e) {}
323   enableButtons();
326 // load a new device
327 function doLoad() {
328   window.browsingContext.topChromeWindow.open(
329     "load_device.xhtml",
330     "loaddevice",
331     "chrome,centerscreen,modal"
332   );
333   ClearDeviceList();
334   RefreshDeviceList();
337 async function deleteSelected() {
338   getSelectedItem();
339   if (selected_module && (await doConfirm("del-module-warning"))) {
340     try {
341       secmoddb.deleteModule(selected_module.name);
342     } catch (e) {
343       doPrompt("del-module-error");
344       return false;
345     }
346     selected_module = null;
347     return true;
348   }
349   return false;
352 async function doUnload() {
353   if (await deleteSelected()) {
354     ClearDeviceList();
355     RefreshDeviceList();
356   }
359 function changePassword() {
360   getSelectedItem();
361   let params = Cc["@mozilla.org/embedcomp/dialogparam;1"].createInstance(
362     Ci.nsIDialogParamBlock
363   );
364   let objects = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
365   objects.appendElement(selected_slot.getToken());
366   params.objects = objects;
367   window.browsingContext.topChromeWindow.openDialog(
368     "changepassword.xhtml",
369     "",
370     "chrome,centerscreen,modal",
371     params
372   );
373   showSlotInfo();
374   enableButtons();
377 // -------------------------------------   Old code
379 function showTokenInfo() {
380   var selected_token = selected_slot.getToken();
381   AddInfoRow("devinfo-label", { label: selected_token.tokenName }, "tok_label");
382   AddInfoRow(
383     "devinfo-man-id",
384     { label: selected_token.tokenManID },
385     "tok_manID"
386   );
387   AddInfoRow(
388     "devinfo-serialnum",
389     { label: selected_token.tokenSerialNumber },
390     "tok_sNum"
391   );
392   AddInfoRow(
393     "devinfo-hwversion",
394     { label: selected_token.tokenHWVersion },
395     "tok_hwv"
396   );
397   AddInfoRow(
398     "devinfo-fwversion",
399     { label: selected_token.tokenFWVersion },
400     "tok_fwv"
401   );
404 function toggleFIPS() {
405   if (!secmoddb.isFIPSEnabled) {
406     // A restriction of FIPS mode is, the password must be set
407     // In FIPS mode the password must be non-empty.
408     // This is different from what we allow in NON-Fips mode.
410     var tokendb = Cc["@mozilla.org/security/pk11tokendb;1"].getService(
411       Ci.nsIPK11TokenDB
412     );
413     var internal_token = tokendb.getInternalKeyToken(); // nsIPK11Token
414     if (!internal_token.hasPassword) {
415       // Token has either no or an empty password.
416       doPrompt("fips-nonempty-primary-password-required");
417       return;
418     }
419   }
421   try {
422     secmoddb.toggleFIPSMode();
423   } catch (e) {
424     doPrompt("unable-to-toggle-fips");
425     return;
426   }
428   // Remove the existing listed modules so that a refresh doesn't display the
429   // module that just changed.
430   ClearDeviceList();
432   RefreshDeviceList();