mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-06 00:55:37 +00:00
175 lines
6.2 KiB
JavaScript
175 lines
6.2 KiB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
"use strict";
|
|
|
|
function debug(s) {
|
|
//dump("-*- PermissionSettings Module: " + s + "\n");
|
|
}
|
|
|
|
const Cu = Components.utils;
|
|
const Cc = Components.classes;
|
|
const Ci = Components.interfaces;
|
|
|
|
this.EXPORTED_SYMBOLS = ["PermissionSettingsModule"];
|
|
|
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
|
Cu.import("resource://gre/modules/Services.jsm");
|
|
Cu.import("resource://gre/modules/PermissionsTable.jsm");
|
|
|
|
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
|
|
"@mozilla.org/parentprocessmessagemanager;1",
|
|
"nsIMessageListenerManager");
|
|
|
|
XPCOMUtils.defineLazyServiceGetter(this,
|
|
"appsService",
|
|
"@mozilla.org/AppsService;1",
|
|
"nsIAppsService");
|
|
|
|
this.PermissionSettingsModule = {
|
|
init: function init() {
|
|
debug("Init");
|
|
ppmm.addMessageListener("PermissionSettings:AddPermission", this);
|
|
Services.obs.addObserver(this, "profile-before-change", false);
|
|
},
|
|
|
|
|
|
_isChangeAllowed: function(aPrincipal, aPermName, aAction, aAppKind) {
|
|
// Bug 812289:
|
|
// Change is allowed from a child process when all of the following
|
|
// conditions stand true:
|
|
// * the action isn't "unknown" (so the change isn't a delete) if the app
|
|
// is installed
|
|
// * the permission already exists on the database
|
|
// * the permission is marked as explicit on the permissions table
|
|
// Note that we *have* to check the first two conditions here because
|
|
// permissionManager doesn't know if it's being called as a result of
|
|
// a parent process or child process request. We could check
|
|
// if the permission is actually explicit (and thus modifiable) or not
|
|
// on permissionManager also but we currently don't.
|
|
let perm =
|
|
Services.perms.testExactPermissionFromPrincipal(aPrincipal,aPermName);
|
|
let isExplicit = isExplicitInPermissionsTable(aPermName, aPrincipal.appStatus, aAppKind);
|
|
|
|
return (aAction === "unknown" &&
|
|
aPrincipal.appStatus === Ci.nsIPrincipal.APP_STATUS_NOT_INSTALLED) ||
|
|
(aAction !== "unknown" &&
|
|
(perm !== Ci.nsIPermissionManager.UNKNOWN_ACTION) &&
|
|
isExplicit);
|
|
},
|
|
|
|
addPermission: function addPermission(aData, aCallbacks) {
|
|
|
|
this._internalAddPermission(aData, true, aCallbacks);
|
|
|
|
},
|
|
|
|
|
|
_internalAddPermission: function _internalAddPermission(aData, aAllowAllChanges, aCallbacks) {
|
|
let uri = Services.io.newURI(aData.origin, null, null);
|
|
let app = appsService.getAppByManifestURL(aData.manifestURL);
|
|
let principal = Services.scriptSecurityManager.getAppCodebasePrincipal(uri, app.localId, aData.browserFlag);
|
|
|
|
let action;
|
|
switch (aData.value)
|
|
{
|
|
case "unknown":
|
|
action = Ci.nsIPermissionManager.UNKNOWN_ACTION;
|
|
break;
|
|
case "allow":
|
|
action = Ci.nsIPermissionManager.ALLOW_ACTION;
|
|
break;
|
|
case "deny":
|
|
action = Ci.nsIPermissionManager.DENY_ACTION;
|
|
break;
|
|
case "prompt":
|
|
action = Ci.nsIPermissionManager.PROMPT_ACTION;
|
|
break;
|
|
default:
|
|
dump("Unsupported PermisionSettings Action: " + aData.value +"\n");
|
|
action = Ci.nsIPermissionManager.UNKNOWN_ACTION;
|
|
}
|
|
|
|
if (aAllowAllChanges ||
|
|
this._isChangeAllowed(principal, aData.type, aData.value, app.kind)) {
|
|
debug("add: " + aData.origin + " " + app.localId + " " + action);
|
|
Services.perms.addFromPrincipal(principal, aData.type, action);
|
|
return true;
|
|
} else {
|
|
debug("add Failure: " + aData.origin + " " + app.localId + " " + action);
|
|
return false; // This isn't currently used, see comment on setPermission
|
|
}
|
|
},
|
|
|
|
getPermission: function getPermission(aPermName, aManifestURL, aOrigin, aBrowserFlag) {
|
|
debug("getPermission: " + aPermName + ", " + aManifestURL + ", " + aOrigin);
|
|
let uri = Services.io.newURI(aOrigin, null, null);
|
|
let appID = appsService.getAppLocalIdByManifestURL(aManifestURL);
|
|
let principal = Services.scriptSecurityManager.getAppCodebasePrincipal(uri, appID, aBrowserFlag);
|
|
let result = Services.perms.testExactPermissionFromPrincipal(principal, aPermName);
|
|
|
|
switch (result)
|
|
{
|
|
case Ci.nsIPermissionManager.UNKNOWN_ACTION:
|
|
return "unknown";
|
|
case Ci.nsIPermissionManager.ALLOW_ACTION:
|
|
return "allow";
|
|
case Ci.nsIPermissionManager.DENY_ACTION:
|
|
return "deny";
|
|
case Ci.nsIPermissionManager.PROMPT_ACTION:
|
|
return "prompt";
|
|
default:
|
|
dump("Unsupported PermissionSettings Action!\n");
|
|
return "unknown";
|
|
}
|
|
},
|
|
|
|
removePermission: function removePermission(aPermName, aManifestURL, aOrigin, aBrowserFlag) {
|
|
let data = {
|
|
type: aPermName,
|
|
origin: aOrigin,
|
|
manifestURL: aManifestURL,
|
|
value: "unknown",
|
|
browserFlag: aBrowserFlag
|
|
};
|
|
this._internalAddPermission(data, true);
|
|
},
|
|
|
|
observe: function observe(aSubject, aTopic, aData) {
|
|
ppmm.removeMessageListener("PermissionSettings:AddPermission", this);
|
|
Services.obs.removeObserver(this, "profile-before-change");
|
|
ppmm = null;
|
|
},
|
|
|
|
receiveMessage: function receiveMessage(aMessage) {
|
|
debug("PermissionSettings::receiveMessage " + aMessage.name);
|
|
let mm = aMessage.target;
|
|
let msg = aMessage.data;
|
|
|
|
let result;
|
|
switch (aMessage.name) {
|
|
case "PermissionSettings:AddPermission":
|
|
let success = false;
|
|
let errorMsg =
|
|
" from a content process with no 'permissions' privileges.";
|
|
if (mm.assertPermission("permissions")) {
|
|
success = this._internalAddPermission(msg, false);
|
|
if (!success) {
|
|
// Just kill the calling process
|
|
mm.assertPermission("permissions-modify-implicit");
|
|
errorMsg = " had an implicit permission change. Child process killed.";
|
|
}
|
|
}
|
|
|
|
if (!success) {
|
|
Cu.reportError("PermissionSettings message " + msg.type + errorMsg);
|
|
return null;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
PermissionSettingsModule.init();
|