Gentoo Archives: gentoo-commits

From: Ian Stakenvicius <axs@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] repo/gentoo:master commit in: www-client/firefox/files/
Date: Tue, 30 Jan 2018 03:57:43
Message-Id: 1517284645.2aa1b5e71f5433e18b1b0066337f6898813e1ed6.axs@gentoo
1 commit: 2aa1b5e71f5433e18b1b0066337f6898813e1ed6
2 Author: Ian Stakenvicius <axs <AT> gentoo <DOT> org>
3 AuthorDate: Tue Jan 30 03:57:02 2018 +0000
4 Commit: Ian Stakenvicius <axs <AT> gentoo <DOT> org>
5 CommitDate: Tue Jan 30 03:57:25 2018 +0000
6 URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=2aa1b5e7
7
8 www-client/firefox: drop unused patch from FILESDIR
9
10 Package-Manager: Portage-2.3.13, Repoman-2.3.3
11
12 .../files/firefox-57.0-pkcs11-backport.patch | 529 ---------------------
13 1 file changed, 529 deletions(-)
14
15 diff --git a/www-client/firefox/files/firefox-57.0-pkcs11-backport.patch b/www-client/firefox/files/firefox-57.0-pkcs11-backport.patch
16 deleted file mode 100644
17 index c07d185f915..00000000000
18 --- a/www-client/firefox/files/firefox-57.0-pkcs11-backport.patch
19 +++ /dev/null
20 @@ -1,529 +0,0 @@
21 -
22 -# HG changeset patch
23 -# User Wouter Verhelst <wouter.verhelst@××××××.be>
24 -# Date 1503417578 -7200
25 -# Node ID 22374473d24f4b4877e50f0b49da3174a70f79ab
26 -# Parent fcb1865dca35554b6d8e9afe017bc7b74c413c72
27 -Bug 1357391 - Implement a PKCS#11 management API r=kmag,zombie
28 -
29 -This WebExtensions API allows to install, remove, and query installed
30 -PKCS#11 modules as well as to query the the status of available PKCS#11
31 -"slots" for a given module.
32 -
33 -Reuses the native application manifests from the "Native Messaging" API,
34 -but using the "pkcs11" type rather than the "stdio" type.
35 -
36 -All calls expect an application name, which is not the PKCS#11 friendly
37 -name (the "description" field in the manifest file is used for that) but
38 -instead the application name in the manifest file.
39 -
40 -MozReview-Commit-ID: 8dHr5QfEaXv
41 -
42 -diff --git a/browser/components/extensions/ext-browser.json b/browser/components/extensions/ext-browser.json
43 ---- a/browser/components/extensions/ext-browser.json
44 -+++ b/browser/components/extensions/ext-browser.json
45 -@@ -117,16 +117,24 @@
46 - "url": "chrome://browser/content/ext-pageAction.js",
47 - "schema": "chrome://browser/content/schemas/page_action.json",
48 - "scopes": ["addon_parent"],
49 - "manifest": ["page_action"],
50 - "paths": [
51 - ["pageAction"]
52 - ]
53 - },
54 -+ "pkcs11": {
55 -+ "url": "chrome://browser/content/ext-pkcs11.js",
56 -+ "schema": "chrome://browser/content/schemas/pkcs11.json",
57 -+ "scopes": ["addon_parent"],
58 -+ "paths": [
59 -+ ["pkcs11"]
60 -+ ]
61 -+ },
62 - "geckoProfiler": {
63 - "url": "chrome://browser/content/ext-geckoProfiler.js",
64 - "schema": "chrome://browser/content/schemas/geckoProfiler.json",
65 - "scopes": ["addon_parent"],
66 - "paths": [
67 - ["geckoProfiler"]
68 - ]
69 - },
70 -diff --git a/browser/components/extensions/ext-pkcs11.js b/browser/components/extensions/ext-pkcs11.js
71 -new file mode 100644
72 ---- /dev/null
73 -+++ b/browser/components/extensions/ext-pkcs11.js
74 -@@ -0,0 +1,145 @@
75 -+"use strict";
76 -+
77 -+XPCOMUtils.defineLazyModuleGetters(this, {
78 -+ ctypes: "resource://gre/modules/ctypes.jsm",
79 -+ NativeManifests: "resource://gre/modules/NativeManifests.jsm",
80 -+ OS: "resource://gre/modules/osfile.jsm",
81 -+});
82 -+
83 -+XPCOMUtils.defineLazyServiceGetter(this,
84 -+ "pkcs11db",
85 -+ "@mozilla.org/security/pkcs11moduledb;1",
86 -+ "nsIPKCS11ModuleDB");
87 -+
88 -+var {DefaultMap} = ExtensionUtils;
89 -+
90 -+const findModuleByPath = function(path) {
91 -+ let modules = pkcs11db.listModules();
92 -+ for (let module of XPCOMUtils.IterSimpleEnumerator(modules, Ci.nsIPKCS11Module)) {
93 -+ if (module && module.libName === path) {
94 -+ return module;
95 -+ }
96 -+ }
97 -+ return null;
98 -+};
99 -+
100 -+this.pkcs11 = class extends ExtensionAPI {
101 -+ getAPI(context) {
102 -+ let manifestCache = new DefaultMap(async name => {
103 -+ let hostInfo = await NativeManifests.lookupManifest("pkcs11", name, context);
104 -+ if (hostInfo) {
105 -+ if (AppConstants.platform === "win") {
106 -+ hostInfo.manifest.path = OS.Path.join(OS.Path.dirname(hostInfo.path), hostInfo.manifest.path);
107 -+ }
108 -+ let manifestLib = OS.Path.basename(hostInfo.manifest.path);
109 -+ if (AppConstants.platform !== "linux") {
110 -+ manifestLib = manifestLib.toLowerCase(manifestLib);
111 -+ }
112 -+ if (manifestLib !== ctypes.libraryName("nssckbi")) {
113 -+ return hostInfo.manifest;
114 -+ }
115 -+ }
116 -+ return Promise.reject({message: `No such PKCS#11 module ${name}`});
117 -+ });
118 -+ return {
119 -+ pkcs11: {
120 -+ /**
121 -+ * Verify whether a given PKCS#11 module is installed.
122 -+ *
123 -+ * @param {string} name The name of the module, as specified in
124 -+ * the manifest file.
125 -+ * @returns {Promise} A Promise that resolves to true if the package
126 -+ * is installed, or false if it is not. May be
127 -+ * rejected if the module could not be found.
128 -+ */
129 -+ async isModuleInstalled(name) {
130 -+ let manifest = await manifestCache.get(name);
131 -+ return findModuleByPath(manifest.path) !== null;
132 -+ },
133 -+ /**
134 -+ * Install a PKCS#11 module
135 -+ *
136 -+ * @param {string} name The name of the module, as specified in
137 -+ * the manifest file.
138 -+ * @param {integer} [flags = 0] Any flags to be passed on to the
139 -+ * nsIPKCS11ModuleDB.addModule method
140 -+ * @returns {Promise} When the Promise resolves, the module will have
141 -+ * been installed. When it is rejected, the module
142 -+ * either is already installed or could not be
143 -+ * installed for some reason.
144 -+ */
145 -+ async installModule(name, flags = 0) {
146 -+ let manifest = await manifestCache.get(name);
147 -+ if (!manifest.description) {
148 -+ return Promise.reject({message: `The description field in the manifest for PKCS#11 module ${name} must have a value`});
149 -+ }
150 -+ pkcs11db.addModule(manifest.description, manifest.path, flags, 0);
151 -+ },
152 -+ /**
153 -+ * Uninstall a PKCS#11 module
154 -+ *
155 -+ * @param {string} name The name of the module, as specified in
156 -+ * the manifest file.
157 -+ * @returns {Promise}. When the Promise resolves, the module will have
158 -+ * been uninstalled. When it is rejected, the
159 -+ * module either was not installed or could not be
160 -+ * uninstalled for some reason.
161 -+ */
162 -+ async uninstallModule(name) {
163 -+ let manifest = await manifestCache.get(name);
164 -+ let module = findModuleByPath(manifest.path);
165 -+ if (!module) {
166 -+ return Promise.reject({message: `The PKCS#11 module ${name} is not loaded`});
167 -+ }
168 -+ pkcs11db.deleteModule(module.name);
169 -+ },
170 -+ /**
171 -+ * Get a list of slots for a given PKCS#11 module, with
172 -+ * information on the token (if any) in the slot.
173 -+ *
174 -+ * The PKCS#11 standard defines slots as an abstract concept
175 -+ * that may or may not have at most one token. In practice, when
176 -+ * using PKCS#11 for smartcards (the most likely use case of
177 -+ * PKCS#11 for Firefox), a slot corresponds to a cardreader, and
178 -+ * a token corresponds to a card.
179 -+ *
180 -+ * @param {string} name The name of the PKCS#11 module, as
181 -+ * specified in the manifest file.
182 -+ * @returns {Promise} A promise that resolves to an array of objects
183 -+ * with two properties. The `name` object contains
184 -+ * the name of the slot; the `token` object is null
185 -+ * if there is no token in the slot, or is an object
186 -+ * describing various properties of the token if
187 -+ * there is.
188 -+ */
189 -+ async getModuleSlots(name) {
190 -+ let manifest = await manifestCache.get(name);
191 -+ let module = findModuleByPath(manifest.path);
192 -+ if (!module) {
193 -+ return Promise.reject({message: `The module ${name} is not installed`});
194 -+ }
195 -+ let rv = [];
196 -+ for (let slot of XPCOMUtils.IterSimpleEnumerator(module.listSlots(), Ci.nsIPKCS11Slot)) {
197 -+ let token = slot.getToken();
198 -+ let slotobj = {
199 -+ name: slot.name,
200 -+ token: null,
201 -+ };
202 -+ if (slot.status != 1 /* SLOT_NOT_PRESENT */) {
203 -+ slotobj.token = {
204 -+ name: token.tokenName,
205 -+ manufacturer: token.tokenManID,
206 -+ HWVersion: token.tokenHWVersion,
207 -+ FWVersion: token.tokenFWVersion,
208 -+ serial: token.tokenSerialNumber,
209 -+ isLoggedIn: token.isLoggedIn(),
210 -+ };
211 -+ }
212 -+ rv.push(slotobj);
213 -+ }
214 -+ return rv;
215 -+ },
216 -+ },
217 -+ };
218 -+ }
219 -+};
220 -diff --git a/browser/components/extensions/jar.mn b/browser/components/extensions/jar.mn
221 ---- a/browser/components/extensions/jar.mn
222 -+++ b/browser/components/extensions/jar.mn
223 -@@ -24,16 +24,17 @@ browser.jar:
224 - content/browser/ext-devtools-network.js
225 - content/browser/ext-devtools-panels.js
226 - content/browser/ext-find.js
227 - content/browser/ext-geckoProfiler.js
228 - content/browser/ext-history.js
229 - content/browser/ext-menus.js
230 - content/browser/ext-omnibox.js
231 - content/browser/ext-pageAction.js
232 -+ content/browser/ext-pkcs11.js
233 - content/browser/ext-sessions.js
234 - content/browser/ext-sidebarAction.js
235 - content/browser/ext-tabs.js
236 - content/browser/ext-url-overrides.js
237 - content/browser/ext-windows.js
238 - content/browser/ext-c-browser.js
239 - content/browser/ext-c-devtools-inspectedWindow.js
240 - content/browser/ext-c-devtools-panels.js
241 -diff --git a/browser/components/extensions/schemas/jar.mn b/browser/components/extensions/schemas/jar.mn
242 ---- a/browser/components/extensions/schemas/jar.mn
243 -+++ b/browser/components/extensions/schemas/jar.mn
244 -@@ -14,13 +14,14 @@ browser.jar:
245 - content/browser/schemas/devtools_panels.json
246 - content/browser/schemas/find.json
247 - content/browser/schemas/geckoProfiler.json
248 - content/browser/schemas/history.json
249 - content/browser/schemas/menus.json
250 - content/browser/schemas/menus_internal.json
251 - content/browser/schemas/omnibox.json
252 - content/browser/schemas/page_action.json
253 -+ content/browser/schemas/pkcs11.json
254 - content/browser/schemas/sessions.json
255 - content/browser/schemas/sidebar_action.json
256 - content/browser/schemas/tabs.json
257 - content/browser/schemas/url_overrides.json
258 - content/browser/schemas/windows.json
259 -diff --git a/browser/components/extensions/schemas/pkcs11.json b/browser/components/extensions/schemas/pkcs11.json
260 -new file mode 100644
261 ---- /dev/null
262 -+++ b/browser/components/extensions/schemas/pkcs11.json
263 -@@ -0,0 +1,76 @@
264 -+[
265 -+ {
266 -+ "namespace": "manifest",
267 -+ "types": [
268 -+ {
269 -+ "$extend": "Permission",
270 -+ "choices": [{
271 -+ "type": "string",
272 -+ "enum": [
273 -+ "pkcs11"
274 -+ ]
275 -+ }]
276 -+ }
277 -+ ]
278 -+ },
279 -+ {
280 -+ "namespace": "pkcs11",
281 -+ "description": "PKCS#11 module management API",
282 -+ "permissions": ["pkcs11"],
283 -+ "functions": [
284 -+ {
285 -+ "name": "isModuleInstalled",
286 -+ "type": "function",
287 -+ "description": "checks whether a PKCS#11 module, given by name, is installed",
288 -+ "async": true,
289 -+ "parameters": [
290 -+ {
291 -+ "name": "name",
292 -+ "type": "string"
293 -+ }
294 -+ ]
295 -+ },
296 -+ {
297 -+ "name": "installModule",
298 -+ "type": "function",
299 -+ "description": "Install a PKCS#11 module with a given name",
300 -+ "async": true,
301 -+ "parameters": [
302 -+ {
303 -+ "name": "name",
304 -+ "type": "string"
305 -+ },
306 -+ {
307 -+ "name": "flags",
308 -+ "type": "integer",
309 -+ "optional": true
310 -+ }
311 -+ ]
312 -+ },
313 -+ {
314 -+ "name": "uninstallModule",
315 -+ "type": "function",
316 -+ "description": "Remove an installed PKCS#11 module from firefox",
317 -+ "async": true,
318 -+ "parameters": [
319 -+ {
320 -+ "name": "name",
321 -+ "type": "string"
322 -+ }
323 -+ ]
324 -+ },
325 -+ {
326 -+ "name": "getModuleSlots",
327 -+ "type": "function",
328 -+ "description": "Enumerate a module's slots, each with their name and whether a token is present",
329 -+ "async": true,
330 -+ "parameters": [
331 -+ {
332 -+ "name": "name",
333 -+ "type": "string"
334 -+ }
335 -+ ]
336 -+ }
337 -+ ]
338 -+ }
339 -+]
340 -diff --git a/browser/components/extensions/test/xpcshell/test_ext_pkcs11_management.js b/browser/components/extensions/test/xpcshell/test_ext_pkcs11_management.js
341 -new file mode 100644
342 ---- /dev/null
343 -+++ b/browser/components/extensions/test/xpcshell/test_ext_pkcs11_management.js
344 -@@ -0,0 +1,168 @@
345 -+"use strict";
346 -+
347 -+XPCOMUtils.defineLazyModuleGetters(this, {
348 -+ ctypes: "resource://gre/modules/ctypes.jsm",
349 -+ MockRegistry: "resource://testing-common/MockRegistry.jsm",
350 -+ OS: "resource://gre/modules/osfile.jsm",
351 -+});
352 -+
353 -+do_get_profile();
354 -+let tmpDir = FileUtils.getDir("TmpD", ["PKCS11"]);
355 -+let slug = AppConstants.platform === "linux" ? "pkcs11-modules" : "PKCS11Modules";
356 -+tmpDir.createUnique(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
357 -+let baseDir = OS.Path.join(tmpDir.path, slug);
358 -+OS.File.makeDir(baseDir);
359 -+
360 -+do_register_cleanup(() => {
361 -+ tmpDir.remove(true);
362 -+});
363 -+
364 -+function getPath(filename) {
365 -+ return OS.Path.join(baseDir, filename);
366 -+}
367 -+
368 -+const testmodule = "../../../../../security/manager/ssl/tests/unit/pkcs11testmodule/" + ctypes.libraryName("pkcs11testmodule");
369 -+
370 -+// This function was inspired by the native messaging test under
371 -+// toolkit/components/extensions
372 -+
373 -+async function setupManifests(modules) {
374 -+ async function writeManifest(module) {
375 -+ let manifest = {
376 -+ name: module.name,
377 -+ description: module.description,
378 -+ path: module.path,
379 -+ type: "pkcs11",
380 -+ allowed_extensions: [module.id],
381 -+ };
382 -+
383 -+ let manifestPath = getPath(`${module.name}.json`);
384 -+ await OS.File.writeAtomic(manifestPath, JSON.stringify(manifest));
385 -+
386 -+ return manifestPath;
387 -+ }
388 -+
389 -+ switch (AppConstants.platform) {
390 -+ case "macosx":
391 -+ case "linux":
392 -+ let dirProvider = {
393 -+ getFile(property) {
394 -+ if (property == "XREUserNativeManifests") {
395 -+ return tmpDir.clone();
396 -+ } else if (property == "XRESysNativeManifests") {
397 -+ return tmpDir.clone();
398 -+ }
399 -+ return null;
400 -+ },
401 -+ };
402 -+
403 -+ Services.dirsvc.registerProvider(dirProvider);
404 -+ do_register_cleanup(() => {
405 -+ Services.dirsvc.unregisterProvider(dirProvider);
406 -+ });
407 -+
408 -+ for (let module of modules) {
409 -+ await writeManifest(module);
410 -+ }
411 -+ break;
412 -+
413 -+ case "win":
414 -+ const REGKEY = String.raw`Software\Mozilla\PKCS11Modules`;
415 -+
416 -+ let registry = new MockRegistry();
417 -+ do_register_cleanup(() => {
418 -+ registry.shutdown();
419 -+ });
420 -+
421 -+ for (let module of modules) {
422 -+ if (!OS.Path.winIsAbsolute(module.path)) {
423 -+ let cwd = await OS.File.getCurrentDirectory();
424 -+ module.path = OS.Path.join(cwd, module.path);
425 -+ }
426 -+ let manifestPath = await writeManifest(module);
427 -+ registry.setValue(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER,
428 -+ `${REGKEY}\\${module.name}`, "", manifestPath);
429 -+ }
430 -+ break;
431 -+
432 -+ default:
433 -+ ok(false, `Loading of PKCS#11 modules is not supported on ${AppConstants.platform}`);
434 -+ }
435 -+}
436 -+
437 -+add_task(async function test_pkcs11() {
438 -+ async function background() {
439 -+ try {
440 -+ let isInstalled = await browser.pkcs11.isModuleInstalled("testmodule");
441 -+ browser.test.assertFalse(isInstalled, "PKCS#11 module is not installed before we install it");
442 -+ await browser.pkcs11.installModule("testmodule", 0);
443 -+ isInstalled = browser.pkcs11.isModuleInstalled("testmodule");
444 -+ browser.test.assertTrue(isInstalled, "PKCS#11 module is installed after we install it");
445 -+ let slots = await browser.pkcs11.getModuleSlots("testmodule");
446 -+ browser.test.assertEq("Test PKCS11 Slot", slots[0].name, "The first slot name matches the expected name");
447 -+ browser.test.assertEq("Test PKCS11 Slot 二", slots[1].name, "The second slot name matches the expected name");
448 -+ browser.test.assertTrue(slots[1].token, "The second slot has a token");
449 -+ browser.test.assertEq("Test PKCS11 Tokeñ 2 Label", slots[1].token.name, "The token name matches the expected name");
450 -+ browser.test.assertEq("Test PKCS11 Manufacturer ID", slots[1].token.manufacturer, "The token manufacturer matches the expected manufacturer");
451 -+ browser.test.assertEq("0.0", slots[1].token.HWVersion, "The token hardware version matches the expected version");
452 -+ browser.test.assertEq("0.0", slots[1].token.FWVersion, "The token firmware version matches the expected version");
453 -+ browser.test.assertEq("", slots[1].token.serial, "The token has no serial number");
454 -+ browser.test.assertFalse(slots[1].token.isLoggedIn, "The token is not logged in");
455 -+ await browser.pkcs11.uninstallModule("testmodule");
456 -+ isInstalled = await browser.pkcs11.isModuleInstalled("testmodule");
457 -+ browser.test.assertFalse(isInstalled, "PKCS#11 module is no longer installed after we uninstall it");
458 -+ await browser.pkcs11.installModule("testmodule");
459 -+ isInstalled = await browser.pkcs11.isModuleInstalled("testmodule");
460 -+ browser.test.assertTrue(isInstalled, "Installing the PKCS#11 module without flags parameter succeeds");
461 -+ await browser.pkcs11.uninstallModule("testmodule");
462 -+ await browser.test.assertRejects(
463 -+ browser.pkcs11.isModuleInstalled("nonexistingmodule"),
464 -+ /No such PKCS#11 module nonexistingmodule/,
465 -+ "We cannot access modules if no JSON file exists");
466 -+ await browser.test.assertRejects(
467 -+ browser.pkcs11.isModuleInstalled("othermodule"),
468 -+ /No such PKCS#11 module othermodule/,
469 -+ "We cannot access modules if we're not listed in the module's manifest file's allowed_extensions key");
470 -+ await browser.test.assertRejects(
471 -+ browser.pkcs11.uninstallModule("internalmodule"),
472 -+ /No such PKCS#11 module internalmodule/,
473 -+ "We cannot uninstall the NSS Builtin Roots Module");
474 -+ browser.test.notifyPass("pkcs11");
475 -+ } catch (e) {
476 -+ browser.test.fail(`Error: ${String(e)} :: ${e.stack}`);
477 -+ browser.test.notifyFail("pkcs11 failed");
478 -+ }
479 -+ }
480 -+
481 -+ await setupManifests([
482 -+ {
483 -+ name: "testmodule",
484 -+ description: "PKCS#11 Test Module",
485 -+ path: testmodule,
486 -+ id: "pkcs11@×××××××××××××.org",
487 -+ },
488 -+ {
489 -+ name: "othermodule",
490 -+ description: "PKCS#11 Test Module",
491 -+ path: testmodule,
492 -+ id: "other@×××××××××××××.org",
493 -+ },
494 -+ {
495 -+ name: "internalmodule",
496 -+ description: "Builtin Roots Module",
497 -+ path: ctypes.libraryName("nssckbi"),
498 -+ id: "pkcs11@×××××××××××××.org",
499 -+ },
500 -+ ]);
501 -+
502 -+ let extension = ExtensionTestUtils.loadExtension({
503 -+ manifest: {
504 -+ permissions: ["pkcs11"],
505 -+ applications: {"gecko": {id: "pkcs11@×××××××××××××.org"}},
506 -+ },
507 -+ background: background,
508 -+ });
509 -+ await extension.startup();
510 -+ await extension.awaitFinish("pkcs11");
511 -+ await extension.unload();
512 -+});
513 -diff --git a/browser/components/extensions/test/xpcshell/xpcshell.ini b/browser/components/extensions/test/xpcshell/xpcshell.ini
514 ---- a/browser/components/extensions/test/xpcshell/xpcshell.ini
515 -+++ b/browser/components/extensions/test/xpcshell/xpcshell.ini
516 -@@ -15,10 +15,11 @@ dupe-manifest =
517 - # For tests which should run in all configurations.
518 - # - xpcshell-remote.ini
519 - # For tests which should only run with both remote extensions and remote content.
520 -
521 - [test_ext_manifest_commands.js]
522 - [test_ext_manifest_omnibox.js]
523 - [test_ext_manifest_permissions.js]
524 - [test_ext_geckoProfiler_schema.js]
525 -+[test_ext_pkcs11_management.js]
526 -
527 - [include:xpcshell-common.ini]
528 -diff --git a/browser/locales/en-US/chrome/browser/browser.properties b/browser/locales/en-US/chrome/browser/browser.properties
529 ---- a/browser/locales/en-US/chrome/browser/browser.properties
530 -+++ b/browser/locales/en-US/chrome/browser/browser.properties
531 -@@ -106,16 +106,17 @@ webextPerms.description.downloads.open=O
532 - webextPerms.description.find=Read the text of all open tabs
533 - webextPerms.description.geolocation=Access your location
534 - webextPerms.description.history=Access browsing history
535 - webextPerms.description.management=Monitor extension usage and manage themes
536 - # LOCALIZATION NOTE (webextPerms.description.nativeMessaging)
537 - # %S will be replaced with the name of the application
538 - webextPerms.description.nativeMessaging=Exchange messages with programs other than %S
539 - webextPerms.description.notifications=Display notifications to you
540 -+webextPerms.description.pkcs11=Provide cryptographic authentication services
541 - webextPerms.description.privacy=Read and modify privacy settings
542 - webextPerms.description.proxy=Control browser proxy settings
543 - webextPerms.description.sessions=Access recently closed tabs
544 - webextPerms.description.tabs=Access browser tabs
545 - webextPerms.description.topSites=Access browsing history
546 - webextPerms.description.unlimitedStorage=Store unlimited amount of client-side data
547 - webextPerms.description.webNavigation=Access browser activity during navigation
548 -
549 -