dom/apps/src/PermissionsTable.jsm

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 "use strict";
michael@0 6
michael@0 7 const Ci = Components.interfaces;
michael@0 8 const Cu = Components.utils;
michael@0 9
michael@0 10 this.EXPORTED_SYMBOLS = [
michael@0 11 "PermissionsTable",
michael@0 12 "PermissionsReverseTable",
michael@0 13 "expandPermissions",
michael@0 14 "appendAccessToPermName",
michael@0 15 "isExplicitInPermissionsTable"
michael@0 16 ];
michael@0 17
michael@0 18 // Permission access flags
michael@0 19 const READONLY = "readonly";
michael@0 20 const CREATEONLY = "createonly";
michael@0 21 const READCREATE = "readcreate";
michael@0 22 const READWRITE = "readwrite";
michael@0 23
michael@0 24 const UNKNOWN_ACTION = Ci.nsIPermissionManager.UNKNOWN_ACTION;
michael@0 25 const ALLOW_ACTION = Ci.nsIPermissionManager.ALLOW_ACTION;
michael@0 26 const DENY_ACTION = Ci.nsIPermissionManager.DENY_ACTION;
michael@0 27 const PROMPT_ACTION = Ci.nsIPermissionManager.PROMPT_ACTION;
michael@0 28
michael@0 29 // Permissions Matrix: https://docs.google.com/spreadsheet/ccc?key=0Akyz_Bqjgf5pdENVekxYRjBTX0dCXzItMnRyUU1RQ0E#gid=0
michael@0 30
michael@0 31 // Permissions that are implicit:
michael@0 32 // battery-status, network-information, vibration,
michael@0 33 // device-capabilities
michael@0 34
michael@0 35 this.PermissionsTable = { geolocation: {
michael@0 36 app: PROMPT_ACTION,
michael@0 37 privileged: PROMPT_ACTION,
michael@0 38 certified: PROMPT_ACTION
michael@0 39 },
michael@0 40 camera: {
michael@0 41 app: DENY_ACTION,
michael@0 42 privileged: PROMPT_ACTION,
michael@0 43 certified: ALLOW_ACTION
michael@0 44 },
michael@0 45 alarms: {
michael@0 46 app: ALLOW_ACTION,
michael@0 47 privileged: ALLOW_ACTION,
michael@0 48 certified: ALLOW_ACTION
michael@0 49 },
michael@0 50 "tcp-socket": {
michael@0 51 app: DENY_ACTION,
michael@0 52 privileged: ALLOW_ACTION,
michael@0 53 certified: ALLOW_ACTION
michael@0 54 },
michael@0 55 "network-events": {
michael@0 56 app: DENY_ACTION,
michael@0 57 privileged: DENY_ACTION,
michael@0 58 certified: ALLOW_ACTION
michael@0 59 },
michael@0 60 contacts: {
michael@0 61 app: DENY_ACTION,
michael@0 62 privileged: PROMPT_ACTION,
michael@0 63 certified: ALLOW_ACTION,
michael@0 64 access: ["read", "write", "create"]
michael@0 65 },
michael@0 66 "device-storage:apps": {
michael@0 67 app: DENY_ACTION,
michael@0 68 privileged: DENY_ACTION,
michael@0 69 certified: ALLOW_ACTION,
michael@0 70 access: ["read"]
michael@0 71 },
michael@0 72 "device-storage:crashes": {
michael@0 73 app: DENY_ACTION,
michael@0 74 privileged: DENY_ACTION,
michael@0 75 certified: ALLOW_ACTION,
michael@0 76 access: ["read"]
michael@0 77 },
michael@0 78 "device-storage:pictures": {
michael@0 79 app: DENY_ACTION,
michael@0 80 privileged: PROMPT_ACTION,
michael@0 81 certified: ALLOW_ACTION,
michael@0 82 access: ["read", "write", "create"]
michael@0 83 },
michael@0 84 "device-storage:videos": {
michael@0 85 app: DENY_ACTION,
michael@0 86 privileged: PROMPT_ACTION,
michael@0 87 certified: ALLOW_ACTION,
michael@0 88 access: ["read", "write", "create"]
michael@0 89 },
michael@0 90 "device-storage:music": {
michael@0 91 app: DENY_ACTION,
michael@0 92 privileged: PROMPT_ACTION,
michael@0 93 certified: ALLOW_ACTION,
michael@0 94 access: ["read", "write", "create"]
michael@0 95 },
michael@0 96 "device-storage:sdcard": {
michael@0 97 app: DENY_ACTION,
michael@0 98 privileged: PROMPT_ACTION,
michael@0 99 certified: ALLOW_ACTION,
michael@0 100 access: ["read", "write", "create"]
michael@0 101 },
michael@0 102 sms: {
michael@0 103 app: DENY_ACTION,
michael@0 104 privileged: DENY_ACTION,
michael@0 105 certified: ALLOW_ACTION
michael@0 106 },
michael@0 107 telephony: {
michael@0 108 app: DENY_ACTION,
michael@0 109 privileged: DENY_ACTION,
michael@0 110 certified: ALLOW_ACTION
michael@0 111 },
michael@0 112 browser: {
michael@0 113 app: DENY_ACTION,
michael@0 114 privileged: ALLOW_ACTION,
michael@0 115 certified: ALLOW_ACTION
michael@0 116 },
michael@0 117 bluetooth: {
michael@0 118 app: DENY_ACTION,
michael@0 119 privileged: DENY_ACTION,
michael@0 120 certified: ALLOW_ACTION
michael@0 121 },
michael@0 122 mobileconnection: {
michael@0 123 app: DENY_ACTION,
michael@0 124 privileged: DENY_ACTION,
michael@0 125 certified: ALLOW_ACTION
michael@0 126 },
michael@0 127 mobilenetwork: {
michael@0 128 app: DENY_ACTION,
michael@0 129 privileged: ALLOW_ACTION,
michael@0 130 certified: ALLOW_ACTION
michael@0 131 },
michael@0 132 power: {
michael@0 133 app: DENY_ACTION,
michael@0 134 privileged: DENY_ACTION,
michael@0 135 certified: ALLOW_ACTION
michael@0 136 },
michael@0 137 push: {
michael@0 138 app: ALLOW_ACTION,
michael@0 139 privileged: ALLOW_ACTION,
michael@0 140 certified: ALLOW_ACTION
michael@0 141 },
michael@0 142 settings: {
michael@0 143 app: DENY_ACTION,
michael@0 144 privileged: DENY_ACTION,
michael@0 145 certified: ALLOW_ACTION,
michael@0 146 access: ["read", "write"],
michael@0 147 additional: ["indexedDB-chrome-settings"]
michael@0 148 },
michael@0 149 permissions: {
michael@0 150 app: DENY_ACTION,
michael@0 151 privileged: DENY_ACTION,
michael@0 152 certified: ALLOW_ACTION
michael@0 153 },
michael@0 154 phonenumberservice: {
michael@0 155 app: DENY_ACTION,
michael@0 156 privileged: DENY_ACTION,
michael@0 157 certified: ALLOW_ACTION
michael@0 158 },
michael@0 159 fmradio: {
michael@0 160 app: DENY_ACTION,
michael@0 161 privileged: ALLOW_ACTION,
michael@0 162 certified: ALLOW_ACTION
michael@0 163 },
michael@0 164 attention: {
michael@0 165 app: DENY_ACTION,
michael@0 166 privileged: DENY_ACTION,
michael@0 167 certified: ALLOW_ACTION
michael@0 168 },
michael@0 169 "webapps-manage": {
michael@0 170 app: DENY_ACTION,
michael@0 171 privileged: DENY_ACTION,
michael@0 172 certified: ALLOW_ACTION
michael@0 173 },
michael@0 174 "backgroundservice": {
michael@0 175 app: DENY_ACTION,
michael@0 176 privileged: DENY_ACTION,
michael@0 177 certified: ALLOW_ACTION
michael@0 178 },
michael@0 179 "desktop-notification": {
michael@0 180 app: ALLOW_ACTION,
michael@0 181 privileged: ALLOW_ACTION,
michael@0 182 certified: ALLOW_ACTION
michael@0 183 },
michael@0 184 "networkstats-manage": {
michael@0 185 app: DENY_ACTION,
michael@0 186 privileged: DENY_ACTION,
michael@0 187 certified: ALLOW_ACTION
michael@0 188 },
michael@0 189 "wifi-manage": {
michael@0 190 app: DENY_ACTION,
michael@0 191 privileged: DENY_ACTION,
michael@0 192 certified: ALLOW_ACTION
michael@0 193 },
michael@0 194 "systemXHR": {
michael@0 195 app: DENY_ACTION,
michael@0 196 privileged: ALLOW_ACTION,
michael@0 197 certified: ALLOW_ACTION
michael@0 198 },
michael@0 199 "voicemail": {
michael@0 200 app: DENY_ACTION,
michael@0 201 privileged: DENY_ACTION,
michael@0 202 certified: ALLOW_ACTION
michael@0 203 },
michael@0 204 "deprecated-hwvideo": {
michael@0 205 app: DENY_ACTION,
michael@0 206 privileged: DENY_ACTION,
michael@0 207 certified: ALLOW_ACTION
michael@0 208 },
michael@0 209 "idle": {
michael@0 210 app: DENY_ACTION,
michael@0 211 privileged: DENY_ACTION,
michael@0 212 certified: ALLOW_ACTION
michael@0 213 },
michael@0 214 "time": {
michael@0 215 app: DENY_ACTION,
michael@0 216 privileged: DENY_ACTION,
michael@0 217 certified: ALLOW_ACTION
michael@0 218 },
michael@0 219 "embed-apps": {
michael@0 220 app: DENY_ACTION,
michael@0 221 privileged: DENY_ACTION,
michael@0 222 certified: ALLOW_ACTION
michael@0 223 },
michael@0 224 "storage": {
michael@0 225 app: ALLOW_ACTION,
michael@0 226 privileged: ALLOW_ACTION,
michael@0 227 certified: ALLOW_ACTION,
michael@0 228 substitute: [
michael@0 229 "indexedDB-unlimited",
michael@0 230 "default-persistent-storage"
michael@0 231 ]
michael@0 232 },
michael@0 233 "background-sensors": {
michael@0 234 app: DENY_ACTION,
michael@0 235 privileged: DENY_ACTION,
michael@0 236 certified: ALLOW_ACTION
michael@0 237 },
michael@0 238 cellbroadcast: {
michael@0 239 app: DENY_ACTION,
michael@0 240 privileged: DENY_ACTION,
michael@0 241 certified: ALLOW_ACTION
michael@0 242 },
michael@0 243 "audio-channel-normal": {
michael@0 244 app: ALLOW_ACTION,
michael@0 245 privileged: ALLOW_ACTION,
michael@0 246 certified: ALLOW_ACTION
michael@0 247 },
michael@0 248 "audio-channel-content": {
michael@0 249 app: ALLOW_ACTION,
michael@0 250 privileged: ALLOW_ACTION,
michael@0 251 certified: ALLOW_ACTION
michael@0 252 },
michael@0 253 "audio-channel-notification": {
michael@0 254 app: DENY_ACTION,
michael@0 255 privileged: ALLOW_ACTION,
michael@0 256 certified: ALLOW_ACTION
michael@0 257 },
michael@0 258 "audio-channel-alarm": {
michael@0 259 app: DENY_ACTION,
michael@0 260 privileged: ALLOW_ACTION,
michael@0 261 certified: ALLOW_ACTION
michael@0 262 },
michael@0 263 "audio-channel-telephony": {
michael@0 264 app: DENY_ACTION,
michael@0 265 privileged: DENY_ACTION,
michael@0 266 certified: ALLOW_ACTION
michael@0 267 },
michael@0 268 "audio-channel-ringer": {
michael@0 269 app: DENY_ACTION,
michael@0 270 privileged: DENY_ACTION,
michael@0 271 certified: ALLOW_ACTION
michael@0 272 },
michael@0 273 "audio-channel-publicnotification": {
michael@0 274 app: DENY_ACTION,
michael@0 275 privileged: DENY_ACTION,
michael@0 276 certified: ALLOW_ACTION
michael@0 277 },
michael@0 278 "open-remote-window": {
michael@0 279 app: DENY_ACTION,
michael@0 280 privileged: DENY_ACTION,
michael@0 281 certified: ALLOW_ACTION
michael@0 282 },
michael@0 283 "input": {
michael@0 284 app: DENY_ACTION,
michael@0 285 privileged: ALLOW_ACTION,
michael@0 286 certified: ALLOW_ACTION
michael@0 287 },
michael@0 288 "input-manage": {
michael@0 289 app: DENY_ACTION,
michael@0 290 privileged: DENY_ACTION,
michael@0 291 certified: ALLOW_ACTION
michael@0 292 },
michael@0 293 "wappush": {
michael@0 294 app: DENY_ACTION,
michael@0 295 privileged: DENY_ACTION,
michael@0 296 certified: ALLOW_ACTION
michael@0 297 },
michael@0 298 "audio-capture": {
michael@0 299 app: PROMPT_ACTION,
michael@0 300 privileged: PROMPT_ACTION,
michael@0 301 certified: PROMPT_ACTION
michael@0 302 },
michael@0 303 "nfc": {
michael@0 304 app: DENY_ACTION,
michael@0 305 privileged: DENY_ACTION,
michael@0 306 certified: ALLOW_ACTION,
michael@0 307 access: ["read", "write"]
michael@0 308 },
michael@0 309 "nfc-manager": {
michael@0 310 app: DENY_ACTION,
michael@0 311 privileged: DENY_ACTION,
michael@0 312 certified: ALLOW_ACTION
michael@0 313 },
michael@0 314 "speaker-control": {
michael@0 315 app: DENY_ACTION,
michael@0 316 privileged: ALLOW_ACTION,
michael@0 317 certified: ALLOW_ACTION
michael@0 318 },
michael@0 319 "downloads": {
michael@0 320 app: DENY_ACTION,
michael@0 321 privileged: DENY_ACTION,
michael@0 322 certified: ALLOW_ACTION
michael@0 323 },
michael@0 324 "video-capture": {
michael@0 325 app: PROMPT_ACTION,
michael@0 326 privileged: PROMPT_ACTION,
michael@0 327 certified: PROMPT_ACTION
michael@0 328 },
michael@0 329 };
michael@0 330
michael@0 331 /**
michael@0 332 * Append access modes to the permission name as suffixes.
michael@0 333 * e.g. permission name 'contacts' with ['read', 'write'] =
michael@0 334 * ['contacts-read', contacts-write']
michael@0 335 * @param string aPermName
michael@0 336 * @param array aAccess
michael@0 337 * @returns array containing access-appended permission names.
michael@0 338 **/
michael@0 339 this.appendAccessToPermName = function appendAccessToPermName(aPermName, aAccess) {
michael@0 340 if (aAccess.length == 0) {
michael@0 341 return [aPermName];
michael@0 342 }
michael@0 343 return aAccess.map(function(aMode) {
michael@0 344 return aPermName + "-" + aMode;
michael@0 345 });
michael@0 346 };
michael@0 347
michael@0 348 /**
michael@0 349 * Expand an access string into multiple permission names,
michael@0 350 * e.g: permission name 'contacts' with 'readwrite' =
michael@0 351 * ['contacts-read', 'contacts-create', 'contacts-write']
michael@0 352 * @param string aPermName
michael@0 353 * @param string aAccess (optional)
michael@0 354 * @returns array containing expanded permission names.
michael@0 355 **/
michael@0 356 this.expandPermissions = function expandPermissions(aPermName, aAccess) {
michael@0 357 if (!PermissionsTable[aPermName]) {
michael@0 358 let errorMsg =
michael@0 359 "PermissionsTable.jsm: expandPermissions: Unknown Permission: " + aPermName;
michael@0 360 Cu.reportError(errorMsg);
michael@0 361 dump(errorMsg);
michael@0 362 return [];
michael@0 363 }
michael@0 364
michael@0 365 const tableEntry = PermissionsTable[aPermName];
michael@0 366
michael@0 367 if (tableEntry.substitute && tableEntry.additional) {
michael@0 368 let errorMsg =
michael@0 369 "PermissionsTable.jsm: expandPermissions: Can't handle both 'substitute' " +
michael@0 370 "and 'additional' entries for permission: " + aPermName;
michael@0 371 Cu.reportError(errorMsg);
michael@0 372 dump(errorMsg);
michael@0 373 return [];
michael@0 374 }
michael@0 375
michael@0 376 if (!aAccess && tableEntry.access ||
michael@0 377 aAccess && !tableEntry.access) {
michael@0 378 let errorMsg =
michael@0 379 "PermissionsTable.jsm: expandPermissions: Invalid access for permission " +
michael@0 380 aPermName + ": " + aAccess + "\n";
michael@0 381 Cu.reportError(errorMsg);
michael@0 382 dump(errorMsg);
michael@0 383 return [];
michael@0 384 }
michael@0 385
michael@0 386 let expandedPermNames = [];
michael@0 387
michael@0 388 if (tableEntry.access && aAccess) {
michael@0 389 let requestedSuffixes = [];
michael@0 390 switch (aAccess) {
michael@0 391 case READONLY:
michael@0 392 requestedSuffixes.push("read");
michael@0 393 break;
michael@0 394 case CREATEONLY:
michael@0 395 requestedSuffixes.push("create");
michael@0 396 break;
michael@0 397 case READCREATE:
michael@0 398 requestedSuffixes.push("read", "create");
michael@0 399 break;
michael@0 400 case READWRITE:
michael@0 401 requestedSuffixes.push("read", "create", "write");
michael@0 402 break;
michael@0 403 default:
michael@0 404 return [];
michael@0 405 }
michael@0 406
michael@0 407 let permArr = appendAccessToPermName(aPermName, requestedSuffixes);
michael@0 408
michael@0 409 // Add the same suffix to each of the additions.
michael@0 410 if (tableEntry.additional) {
michael@0 411 for each (let additional in tableEntry.additional) {
michael@0 412 permArr = permArr.concat(appendAccessToPermName(additional, requestedSuffixes));
michael@0 413 }
michael@0 414 }
michael@0 415
michael@0 416 // Only add the suffixed version if the suffix exists in the table.
michael@0 417 for (let idx in permArr) {
michael@0 418 let suffix = requestedSuffixes[idx % requestedSuffixes.length];
michael@0 419 if (tableEntry.access.indexOf(suffix) != -1) {
michael@0 420 expandedPermNames.push(permArr[idx]);
michael@0 421 }
michael@0 422 }
michael@0 423 } else if (tableEntry.substitute) {
michael@0 424 expandedPermNames = expandedPermNames.concat(tableEntry.substitute);
michael@0 425 } else {
michael@0 426 expandedPermNames.push(aPermName);
michael@0 427 // Include each of the additions exactly as they appear in the table.
michael@0 428 if (tableEntry.additional) {
michael@0 429 expandedPermNames = expandedPermNames.concat(tableEntry.additional);
michael@0 430 }
michael@0 431 }
michael@0 432
michael@0 433 return expandedPermNames;
michael@0 434 };
michael@0 435
michael@0 436 this.PermissionsReverseTable = (function () {
michael@0 437 // PermissionsTable as it is works well for direct searches, but not
michael@0 438 // so well for reverse ones (that is, if I get something like
michael@0 439 // device-storage:music-read or indexedDB-chrome-settings-read how
michael@0 440 // do I know which permission it really is? Hence this table is
michael@0 441 // born. The idea is that
michael@0 442 // reverseTable[device-storage:music-read] should return
michael@0 443 // device-storage:music
michael@0 444 let reverseTable = {};
michael@0 445
michael@0 446 for (let permName in PermissionsTable) {
michael@0 447 let permAliases;
michael@0 448 if (PermissionsTable[permName].access) {
michael@0 449 permAliases = expandPermissions(permName, "readwrite");
michael@0 450 } else {
michael@0 451 permAliases = expandPermissions(permName);
michael@0 452 }
michael@0 453 for (let i = 0; i < permAliases.length; i++) {
michael@0 454 reverseTable[permAliases[i]] = permName;
michael@0 455 }
michael@0 456 }
michael@0 457
michael@0 458 return reverseTable;
michael@0 459
michael@0 460 })();
michael@0 461
michael@0 462 this.isExplicitInPermissionsTable = function(aPermName, aIntStatus) {
michael@0 463
michael@0 464 // Check to see if the 'webapp' is app/privileged/certified.
michael@0 465 let appStatus;
michael@0 466 switch (aIntStatus) {
michael@0 467 case Ci.nsIPrincipal.APP_STATUS_CERTIFIED:
michael@0 468 appStatus = "certified";
michael@0 469 break;
michael@0 470 case Ci.nsIPrincipal.APP_STATUS_PRIVILEGED:
michael@0 471 appStatus = "privileged";
michael@0 472 break;
michael@0 473 default: // If it isn't certified or privileged, it's app
michael@0 474 appStatus = "app";
michael@0 475 break;
michael@0 476 }
michael@0 477
michael@0 478 let realPerm = PermissionsReverseTable[aPermName];
michael@0 479
michael@0 480 if (realPerm) {
michael@0 481 return (PermissionsTable[realPerm][appStatus] ==
michael@0 482 Ci.nsIPermissionManager.PROMPT_ACTION);
michael@0 483 } else {
michael@0 484 return false;
michael@0 485 }
michael@0 486 }

mercurial