зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1196988 - Remove THA support. r=gwagner
This commit is contained in:
Родитель
d02d04187e
Коммит
3a47f061c9
|
@ -436,8 +436,6 @@ pref("browser.dom.window.dump.enabled", false);
|
||||||
// Default Content Security Policy to apply to certified apps.
|
// Default Content Security Policy to apply to certified apps.
|
||||||
// If you change this CSP, make sure to update the fast path in nsCSPService.cpp
|
// If you change this CSP, make sure to update the fast path in nsCSPService.cpp
|
||||||
pref("security.apps.certified.CSP.default", "default-src * data: blob:; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline' app://theme.gaiamobile.org");
|
pref("security.apps.certified.CSP.default", "default-src * data: blob:; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline' app://theme.gaiamobile.org");
|
||||||
// Default Content Security Policy to apply to trusted apps.
|
|
||||||
pref("security.apps.trusted.CSP.default", "default-src * data: blob:; object-src 'none'; frame-src 'none'");
|
|
||||||
|
|
||||||
// handle links targeting new windows
|
// handle links targeting new windows
|
||||||
// 1=current window/tab, 2=new window, 3=new tab in most recent window
|
// 1=current window/tab, 2=new window, 3=new tab in most recent window
|
||||||
|
|
|
@ -250,7 +250,7 @@ AppValidator.prototype.validateLaunchPath = function (manifest) {
|
||||||
|
|
||||||
AppValidator.prototype.validateType = function (manifest) {
|
AppValidator.prototype.validateType = function (manifest) {
|
||||||
let appType = manifest.type || "web";
|
let appType = manifest.type || "web";
|
||||||
if (["web", "trusted", "privileged", "certified"].indexOf(appType) === -1) {
|
if (["web", "privileged", "certified"].indexOf(appType) === -1) {
|
||||||
this.error(strings.formatStringFromName("validator.invalidAppType", [appType], 1));
|
this.error(strings.formatStringFromName("validator.invalidAppType", [appType], 1));
|
||||||
} else if (this.type == "hosted" &&
|
} else if (this.type == "hosted" &&
|
||||||
["certified", "privileged"].indexOf(appType) !== -1) {
|
["certified", "privileged"].indexOf(appType) !== -1) {
|
||||||
|
|
|
@ -26,8 +26,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "appsService",
|
||||||
"@mozilla.org/AppsService;1",
|
"@mozilla.org/AppsService;1",
|
||||||
"nsIAppsService");
|
"nsIAppsService");
|
||||||
|
|
||||||
// Shared code for AppsServiceChild.jsm, TrustedHostedAppsUtils.jsm,
|
// Shared code for AppsServiceChild.jsm, Webapps.jsm and Webapps.js
|
||||||
// Webapps.jsm and Webapps.js
|
|
||||||
|
|
||||||
this.EXPORTED_SYMBOLS =
|
this.EXPORTED_SYMBOLS =
|
||||||
["AppsUtils", "ManifestHelper", "isAbsoluteURI", "mozIApplication"];
|
["AppsUtils", "ManifestHelper", "isAbsoluteURI", "mozIApplication"];
|
||||||
|
@ -300,9 +299,7 @@ this.AppsUtils = {
|
||||||
return Services.prefs.getCharPref("security.apps.privileged.CSP.default");
|
return Services.prefs.getCharPref("security.apps.privileged.CSP.default");
|
||||||
break;
|
break;
|
||||||
case Ci.nsIPrincipal.APP_STATUS_INSTALLED:
|
case Ci.nsIPrincipal.APP_STATUS_INSTALLED:
|
||||||
return app.kind == "hosted-trusted"
|
return "";
|
||||||
? Services.prefs.getCharPref("security.apps.trusted.CSP.default")
|
|
||||||
: "";
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch(e) {}
|
} catch(e) {}
|
||||||
|
@ -605,7 +602,6 @@ this.AppsUtils = {
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case "web":
|
case "web":
|
||||||
case "trusted":
|
|
||||||
return Ci.nsIPrincipal.APP_STATUS_INSTALLED;
|
return Ci.nsIPrincipal.APP_STATUS_INSTALLED;
|
||||||
case "privileged":
|
case "privileged":
|
||||||
return Ci.nsIPrincipal.APP_STATUS_PRIVILEGED;
|
return Ci.nsIPrincipal.APP_STATUS_PRIVILEGED;
|
||||||
|
|
|
@ -107,9 +107,6 @@ this.PermissionsInstaller = {
|
||||||
break;
|
break;
|
||||||
case Ci.nsIPrincipal.APP_STATUS_INSTALLED:
|
case Ci.nsIPrincipal.APP_STATUS_INSTALLED:
|
||||||
appStatus = "app";
|
appStatus = "app";
|
||||||
if (aApp.kind == "hosted-trusted") {
|
|
||||||
appStatus = "trusted";
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Cannot determine app type, abort install by throwing an error.
|
// Cannot determine app type, abort install by throwing an error.
|
||||||
|
|
|
@ -35,153 +35,129 @@ const PROMPT_ACTION = Ci.nsIPermissionManager.PROMPT_ACTION;
|
||||||
|
|
||||||
this.PermissionsTable = { geolocation: {
|
this.PermissionsTable = { geolocation: {
|
||||||
app: PROMPT_ACTION,
|
app: PROMPT_ACTION,
|
||||||
trusted: PROMPT_ACTION,
|
|
||||||
privileged: PROMPT_ACTION,
|
privileged: PROMPT_ACTION,
|
||||||
certified: PROMPT_ACTION
|
certified: PROMPT_ACTION
|
||||||
},
|
},
|
||||||
"geolocation-noprompt": {
|
"geolocation-noprompt": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION,
|
certified: ALLOW_ACTION,
|
||||||
substitute: ["geolocation"]
|
substitute: ["geolocation"]
|
||||||
},
|
},
|
||||||
camera: {
|
camera: {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: PROMPT_ACTION,
|
|
||||||
privileged: PROMPT_ACTION,
|
privileged: PROMPT_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
alarms: {
|
alarms: {
|
||||||
app: ALLOW_ACTION,
|
app: ALLOW_ACTION,
|
||||||
trusted: ALLOW_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"tcp-socket": {
|
"tcp-socket": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"udp-socket": {
|
"udp-socket": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"network-events": {
|
"network-events": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
contacts: {
|
contacts: {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: PROMPT_ACTION,
|
privileged: PROMPT_ACTION,
|
||||||
certified: ALLOW_ACTION,
|
certified: ALLOW_ACTION,
|
||||||
access: ["read", "write", "create"]
|
access: ["read", "write", "create"]
|
||||||
},
|
},
|
||||||
"device-storage:apps": {
|
"device-storage:apps": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION,
|
certified: ALLOW_ACTION,
|
||||||
access: ["read"]
|
access: ["read"]
|
||||||
},
|
},
|
||||||
"device-storage:crashes": {
|
"device-storage:crashes": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION,
|
certified: ALLOW_ACTION,
|
||||||
access: ["read"]
|
access: ["read"]
|
||||||
},
|
},
|
||||||
"device-storage:pictures": {
|
"device-storage:pictures": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: PROMPT_ACTION,
|
|
||||||
privileged: PROMPT_ACTION,
|
privileged: PROMPT_ACTION,
|
||||||
certified: ALLOW_ACTION,
|
certified: ALLOW_ACTION,
|
||||||
access: ["read", "write", "create"]
|
access: ["read", "write", "create"]
|
||||||
},
|
},
|
||||||
"device-storage:videos": {
|
"device-storage:videos": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: PROMPT_ACTION,
|
|
||||||
privileged: PROMPT_ACTION,
|
privileged: PROMPT_ACTION,
|
||||||
certified: ALLOW_ACTION,
|
certified: ALLOW_ACTION,
|
||||||
access: ["read", "write", "create"]
|
access: ["read", "write", "create"]
|
||||||
},
|
},
|
||||||
"device-storage:music": {
|
"device-storage:music": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: PROMPT_ACTION,
|
|
||||||
privileged: PROMPT_ACTION,
|
privileged: PROMPT_ACTION,
|
||||||
certified: ALLOW_ACTION,
|
certified: ALLOW_ACTION,
|
||||||
access: ["read", "write", "create"]
|
access: ["read", "write", "create"]
|
||||||
},
|
},
|
||||||
"device-storage:sdcard": {
|
"device-storage:sdcard": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: PROMPT_ACTION,
|
|
||||||
privileged: PROMPT_ACTION,
|
privileged: PROMPT_ACTION,
|
||||||
certified: ALLOW_ACTION,
|
certified: ALLOW_ACTION,
|
||||||
access: ["read", "write", "create"]
|
access: ["read", "write", "create"]
|
||||||
},
|
},
|
||||||
sms: {
|
sms: {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
telephony: {
|
telephony: {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
browser: {
|
browser: {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"browser:universalxss": {
|
"browser:universalxss": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
bluetooth: {
|
bluetooth: {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
mobileconnection: {
|
mobileconnection: {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
mobilenetwork: {
|
mobilenetwork: {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
power: {
|
power: {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
push: {
|
push: {
|
||||||
app: ALLOW_ACTION,
|
app: ALLOW_ACTION,
|
||||||
trusted: ALLOW_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
settings: {
|
settings: {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION,
|
certified: ALLOW_ACTION,
|
||||||
access: ["read", "write"],
|
access: ["read", "write"],
|
||||||
|
@ -192,287 +168,240 @@ this.PermissionsTable = { geolocation: {
|
||||||
// handed out by SpecialPowers.
|
// handed out by SpecialPowers.
|
||||||
"settings-clear": {
|
"settings-clear": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: DENY_ACTION,
|
certified: DENY_ACTION,
|
||||||
additional: ["indexedDB-chrome-settings", "settings-api"]
|
additional: ["indexedDB-chrome-settings", "settings-api"]
|
||||||
},
|
},
|
||||||
permissions: {
|
permissions: {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
phonenumberservice: {
|
phonenumberservice: {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
fmradio: {
|
fmradio: {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
attention: {
|
attention: {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"global-clickthrough-overlay": {
|
"global-clickthrough-overlay": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"moz-attention": {
|
"moz-attention": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION,
|
certified: ALLOW_ACTION,
|
||||||
substitute: ["attention"]
|
substitute: ["attention"]
|
||||||
},
|
},
|
||||||
"webapps-manage": {
|
"webapps-manage": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"homescreen-webapps-manage": {
|
"homescreen-webapps-manage": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"backgroundservice": {
|
"backgroundservice": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"desktop-notification": {
|
"desktop-notification": {
|
||||||
app: ALLOW_ACTION,
|
app: ALLOW_ACTION,
|
||||||
trusted: ALLOW_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"networkstats-manage": {
|
"networkstats-manage": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"resourcestats-manage": {
|
"resourcestats-manage": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"wifi-manage": {
|
"wifi-manage": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"systemXHR": {
|
"systemXHR": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"voicemail": {
|
"voicemail": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"idle": {
|
"idle": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"time": {
|
"time": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"embed-apps": {
|
"embed-apps": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"embed-widgets": {
|
"embed-widgets": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"background-sensors": {
|
"background-sensors": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
cellbroadcast: {
|
cellbroadcast: {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"audio-channel-normal": {
|
"audio-channel-normal": {
|
||||||
app: ALLOW_ACTION,
|
app: ALLOW_ACTION,
|
||||||
trusted: ALLOW_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"audio-channel-content": {
|
"audio-channel-content": {
|
||||||
app: ALLOW_ACTION,
|
app: ALLOW_ACTION,
|
||||||
trusted: ALLOW_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"audio-channel-notification": {
|
"audio-channel-notification": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"audio-channel-alarm": {
|
"audio-channel-alarm": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"audio-channel-system": {
|
"audio-channel-system": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"audio-channel-telephony": {
|
"audio-channel-telephony": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"moz-audio-channel-telephony": {
|
"moz-audio-channel-telephony": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION,
|
certified: ALLOW_ACTION,
|
||||||
substitute: ["audio-channel-telephony"]
|
substitute: ["audio-channel-telephony"]
|
||||||
},
|
},
|
||||||
"audio-channel-ringer": {
|
"audio-channel-ringer": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"moz-audio-channel-ringer": {
|
"moz-audio-channel-ringer": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION,
|
certified: ALLOW_ACTION,
|
||||||
substitute: ["audio-channel-ringer"]
|
substitute: ["audio-channel-ringer"]
|
||||||
},
|
},
|
||||||
"audio-channel-publicnotification": {
|
"audio-channel-publicnotification": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: ALLOW_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"open-remote-window": {
|
"open-remote-window": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"input": {
|
"input": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"input-manage": {
|
"input-manage": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"wappush": {
|
"wappush": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"audio-capture": {
|
"audio-capture": {
|
||||||
app: PROMPT_ACTION,
|
app: PROMPT_ACTION,
|
||||||
trusted: PROMPT_ACTION,
|
|
||||||
privileged: PROMPT_ACTION,
|
privileged: PROMPT_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"audio-capture:3gpp": {
|
"audio-capture:3gpp": {
|
||||||
app: DENY_ACTION,
|
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
|
||||||
certified: ALLOW_ACTION
|
|
||||||
},
|
|
||||||
"nfc": {
|
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
|
certified: ALLOW_ACTION
|
||||||
|
},
|
||||||
|
"nfc": {
|
||||||
|
app: DENY_ACTION,
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"nfc-share": {
|
"nfc-share": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"nfc-manager": {
|
"nfc-manager": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"nfc-hci-events": {
|
"nfc-hci-events": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"speaker-control": {
|
"speaker-control": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"downloads": {
|
"downloads": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"video-capture": {
|
"video-capture": {
|
||||||
app: PROMPT_ACTION,
|
app: PROMPT_ACTION,
|
||||||
trusted: PROMPT_ACTION,
|
|
||||||
privileged: PROMPT_ACTION,
|
privileged: PROMPT_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"feature-detection": {
|
"feature-detection": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"mobileid": {
|
"mobileid": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: PROMPT_ACTION,
|
privileged: PROMPT_ACTION,
|
||||||
certified: PROMPT_ACTION
|
certified: PROMPT_ACTION
|
||||||
},
|
},
|
||||||
|
@ -481,33 +410,28 @@ this.PermissionsTable = { geolocation: {
|
||||||
// of web prompt composed permissions in tests.
|
// of web prompt composed permissions in tests.
|
||||||
"test-permission": {
|
"test-permission": {
|
||||||
app: PROMPT_ACTION,
|
app: PROMPT_ACTION,
|
||||||
trusted: PROMPT_ACTION,
|
|
||||||
privileged: PROMPT_ACTION,
|
privileged: PROMPT_ACTION,
|
||||||
certified: ALLOW_ACTION,
|
certified: ALLOW_ACTION,
|
||||||
access: ["read", "write", "create"]
|
access: ["read", "write", "create"]
|
||||||
},
|
},
|
||||||
"firefox-accounts": {
|
"firefox-accounts": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"moz-firefox-accounts": {
|
"moz-firefox-accounts": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: PROMPT_ACTION,
|
privileged: PROMPT_ACTION,
|
||||||
certified: ALLOW_ACTION,
|
certified: ALLOW_ACTION,
|
||||||
substitute: ["firefox-accounts"]
|
substitute: ["firefox-accounts"]
|
||||||
},
|
},
|
||||||
"themeable": {
|
"themeable": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"settings:wallpaper.image": {
|
"settings:wallpaper.image": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION,
|
certified: ALLOW_ACTION,
|
||||||
access: ["read", "write"],
|
access: ["read", "write"],
|
||||||
|
@ -515,67 +439,56 @@ this.PermissionsTable = { geolocation: {
|
||||||
},
|
},
|
||||||
"engineering-mode": {
|
"engineering-mode": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"tv": {
|
"tv": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"before-after-keyboard-event": {
|
"before-after-keyboard-event": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"presentation-device-manage": {
|
"presentation-device-manage": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"requestsync-manager": {
|
"requestsync-manager": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"secureelement-manage": {
|
"secureelement-manage": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"inputport": {
|
"inputport": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"external-app": {
|
"external-app": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"system-update": {
|
"system-update": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"presentation": {
|
"presentation": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: ALLOW_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"open-hidden-window": {
|
"open-hidden-window": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
trusted: DENY_ACTION,
|
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
|
@ -728,7 +641,7 @@ this.isExplicitInPermissionsTable = function(aPermName, aIntStatus, aAppKind) {
|
||||||
appStatus = "privileged";
|
appStatus = "privileged";
|
||||||
break;
|
break;
|
||||||
default: // If it isn't certified or privileged, it's app
|
default: // If it isn't certified or privileged, it's app
|
||||||
appStatus = aAppKind == "hosted-trusted" ? "trusted" : "app";
|
appStatus = "app";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,6 @@ const APP_TRUSTED_ROOTS= ["AppMarketplaceProdPublicRoot",
|
||||||
"AppMarketplaceDevPublicRoot",
|
"AppMarketplaceDevPublicRoot",
|
||||||
"AppMarketplaceDevReviewersRoot",
|
"AppMarketplaceDevReviewersRoot",
|
||||||
"AppMarketplaceStageRoot",
|
"AppMarketplaceStageRoot",
|
||||||
"TrustedHostedAppPublicRoot",
|
|
||||||
"TrustedHostedAppTestRoot",
|
|
||||||
"AppXPCShellRoot"];
|
"AppXPCShellRoot"];
|
||||||
|
|
||||||
this.TrustedRootCertificate = {
|
this.TrustedRootCertificate = {
|
||||||
|
|
|
@ -1,281 +0,0 @@
|
||||||
/* 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/. */
|
|
||||||
|
|
||||||
/* global Components, Services, dump, AppsUtils, NetUtil, XPCOMUtils */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const Cu = Components.utils;
|
|
||||||
const Cc = Components.classes;
|
|
||||||
const Ci = Components.interfaces;
|
|
||||||
const Cr = Components.results;
|
|
||||||
const signatureFileExtension = ".sig";
|
|
||||||
|
|
||||||
this.EXPORTED_SYMBOLS = ["TrustedHostedAppsUtils"];
|
|
||||||
|
|
||||||
Cu.import("resource://gre/modules/AppsUtils.jsm");
|
|
||||||
Cu.import("resource://gre/modules/Promise.jsm");
|
|
||||||
Cu.import("resource://gre/modules/Services.jsm");
|
|
||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
|
||||||
|
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
|
||||||
"resource://gre/modules/NetUtil.jsm");
|
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
// On Android, define the "debug" function as a binding of the "d" function
|
|
||||||
// from the AndroidLog module so it gets the "debug" priority and a log tag.
|
|
||||||
// We always report debug messages on Android because it's unnecessary
|
|
||||||
// to restrict reporting, per bug 1003469.
|
|
||||||
let debug = Cu
|
|
||||||
.import("resource://gre/modules/AndroidLog.jsm", {})
|
|
||||||
.AndroidLog.d.bind(null, "TrustedHostedAppsUtils");
|
|
||||||
#else
|
|
||||||
// Elsewhere, report debug messages only if dom.mozApps.debug is set to true.
|
|
||||||
// The pref is only checked once, on startup, so restart after changing it.
|
|
||||||
let debug = Services.prefs.getBoolPref("dom.mozApps.debug") ?
|
|
||||||
aMsg => dump("-*- TrustedHostedAppsUtils.jsm : " + aMsg + "\n") :
|
|
||||||
() => {};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verification functions for Trusted Hosted Apps.
|
|
||||||
*/
|
|
||||||
this.TrustedHostedAppsUtils = {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the given host is pinned in the CA pinning database.
|
|
||||||
*/
|
|
||||||
isHostPinned: function (aUrl) {
|
|
||||||
let uri;
|
|
||||||
try {
|
|
||||||
uri = Services.io.newURI(aUrl, null, null);
|
|
||||||
} catch(e) {
|
|
||||||
debug("Host parsing failed: " + e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: use nsSiteSecurityService.isSecureURI()
|
|
||||||
if (!uri.host || "https" != uri.scheme) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check certificate pinning
|
|
||||||
let siteSecurityService;
|
|
||||||
try {
|
|
||||||
siteSecurityService = Cc["@mozilla.org/ssservice;1"]
|
|
||||||
.getService(Ci.nsISiteSecurityService);
|
|
||||||
} catch (e) {
|
|
||||||
debug("nsISiteSecurityService error: " + e);
|
|
||||||
// unrecoverable error, don't bug the user
|
|
||||||
throw "CERTDB_ERROR";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (siteSecurityService.isSecureHost(Ci.nsISiteSecurityService.HEADER_HPKP,
|
|
||||||
uri.host, 0)) {
|
|
||||||
debug("\tvalid certificate pinning for host: " + uri.host + "\n");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
debug("\tHost NOT pinned: " + uri.host + "\n");
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Take a CSP policy string as input and ensure that it contains at
|
|
||||||
* least the directives that are required ('script-src' and
|
|
||||||
* 'style-src'). If the CSP policy string is 'undefined' or does
|
|
||||||
* not contain some of the required csp directives the function will
|
|
||||||
* return empty list with status set to false. Otherwise a parsed
|
|
||||||
* list of the unique sources listed from the required csp
|
|
||||||
* directives is returned.
|
|
||||||
*/
|
|
||||||
getCSPWhiteList: function(aCsp) {
|
|
||||||
let isValid = false;
|
|
||||||
let whiteList = [];
|
|
||||||
let requiredDirectives = [ "script-src", "style-src" ];
|
|
||||||
|
|
||||||
if (aCsp) {
|
|
||||||
let validDirectives = [];
|
|
||||||
let directives = aCsp.split(";");
|
|
||||||
// TODO: Use nsIContentSecurityPolicy
|
|
||||||
directives
|
|
||||||
.map(aDirective => aDirective.trim().split(" "))
|
|
||||||
.filter(aList => aList.length > 1)
|
|
||||||
// we only restrict on requiredDirectives
|
|
||||||
.filter(aList => (requiredDirectives.indexOf(aList[0]) != -1))
|
|
||||||
.forEach(aList => {
|
|
||||||
// aList[0] contains the directive name.
|
|
||||||
// aList[1..n] contains sources.
|
|
||||||
let directiveName = aList.shift();
|
|
||||||
let sources = aList;
|
|
||||||
|
|
||||||
if ((-1 == validDirectives.indexOf(directiveName))) {
|
|
||||||
validDirectives.push(directiveName);
|
|
||||||
}
|
|
||||||
whiteList.push(...sources.filter(
|
|
||||||
// 'self' is checked separately during manifest check
|
|
||||||
aSource => (aSource !="'self'" && whiteList.indexOf(aSource) == -1)
|
|
||||||
));
|
|
||||||
});
|
|
||||||
|
|
||||||
// Check if all required directives are present.
|
|
||||||
isValid = requiredDirectives.length === validDirectives.length;
|
|
||||||
|
|
||||||
if (!isValid) {
|
|
||||||
debug("White list doesn't contain all required directives!");
|
|
||||||
whiteList = [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
debug("White list contains " + whiteList.length + " hosts");
|
|
||||||
return { list: whiteList, valid: isValid };
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify that the given csp is valid:
|
|
||||||
* 1. contains required directives "script-src" and "style-src"
|
|
||||||
* 2. required directives contain only "https" URLs
|
|
||||||
* 3. domains of the restricted sources exist in the CA pinning database
|
|
||||||
*/
|
|
||||||
verifyCSPWhiteList: function(aCsp) {
|
|
||||||
let domainWhitelist = this.getCSPWhiteList(aCsp);
|
|
||||||
if (!domainWhitelist.valid) {
|
|
||||||
debug("TRUSTED_APPLICATION_WHITELIST_PARSING_FAILED");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!domainWhitelist.list.every(aUrl => this.isHostPinned(aUrl))) {
|
|
||||||
debug("TRUSTED_APPLICATION_WHITELIST_VALIDATION_FAILED");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
_verifySignedFile: function(aManifestStream, aSignatureStream, aCertDb) {
|
|
||||||
let deferred = Promise.defer();
|
|
||||||
|
|
||||||
let root = Ci.nsIX509CertDB.TrustedHostedAppPublicRoot;
|
|
||||||
try {
|
|
||||||
// Check if we should use the test certificates.
|
|
||||||
// Please note that this should be changed if we ever allow chages to the
|
|
||||||
// prefs since that would create a way for an attacker to use the test
|
|
||||||
// root for real apps.
|
|
||||||
let useTrustedAppTestCerts = Services.prefs
|
|
||||||
.getBoolPref("dom.mozApps.use_trustedapp_test_certs");
|
|
||||||
if (useTrustedAppTestCerts) {
|
|
||||||
root = Ci.nsIX509CertDB.TrustedHostedAppTestRoot;
|
|
||||||
}
|
|
||||||
} catch (ex) { }
|
|
||||||
|
|
||||||
aCertDb.verifySignedManifestAsync(
|
|
||||||
root, aManifestStream, aSignatureStream,
|
|
||||||
function(aRv, aCert) {
|
|
||||||
debug("Signature verification returned code, cert & root: " + aRv + " " + aCert + " " + root);
|
|
||||||
if (Components.isSuccessCode(aRv)) {
|
|
||||||
deferred.resolve(aCert);
|
|
||||||
} else if (aRv == Cr.NS_ERROR_FILE_CORRUPTED ||
|
|
||||||
aRv == Cr.NS_ERROR_SIGNED_MANIFEST_FILE_INVALID) {
|
|
||||||
deferred.reject("MANIFEST_SIGNATURE_FILE_INVALID");
|
|
||||||
} else {
|
|
||||||
deferred.reject("MANIFEST_SIGNATURE_VERIFICATION_ERROR");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return deferred.promise;
|
|
||||||
},
|
|
||||||
|
|
||||||
verifySignedManifest: function(aApp, aAppId) {
|
|
||||||
let deferred = Promise.defer();
|
|
||||||
|
|
||||||
let certDb;
|
|
||||||
try {
|
|
||||||
certDb = Cc["@mozilla.org/security/x509certdb;1"]
|
|
||||||
.getService(Ci.nsIX509CertDB);
|
|
||||||
} catch (e) {
|
|
||||||
debug("nsIX509CertDB error: " + e);
|
|
||||||
// unrecoverable error, don't bug the user
|
|
||||||
throw "CERTDB_ERROR";
|
|
||||||
}
|
|
||||||
|
|
||||||
let principal = Services.scriptSecurityManager.getAppCodebasePrincipal(
|
|
||||||
aApp.origin, aApp.localId, false);
|
|
||||||
|
|
||||||
let mRequestChannel = NetUtil.newChannel({
|
|
||||||
uri: aApp.manifestURL,
|
|
||||||
loadingPrincipal: principal,
|
|
||||||
contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER}
|
|
||||||
).QueryInterface(Ci.nsIHttpChannel);
|
|
||||||
mRequestChannel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
|
|
||||||
mRequestChannel.notificationCallbacks =
|
|
||||||
AppsUtils.createLoadContext(aAppId, false);
|
|
||||||
|
|
||||||
// The manifest signature must be located at the same path as the
|
|
||||||
// manifest and have the same file name, only the file extension
|
|
||||||
// should differ. Any fragment or query parameter will be ignored.
|
|
||||||
let signatureURL;
|
|
||||||
try {
|
|
||||||
let mURL = Cc["@mozilla.org/network/io-service;1"]
|
|
||||||
.getService(Ci.nsIIOService)
|
|
||||||
.newURI(aApp.manifestURL, null, null)
|
|
||||||
.QueryInterface(Ci.nsIURL);
|
|
||||||
signatureURL = mURL.prePath +
|
|
||||||
mURL.directory + mURL.fileBaseName + signatureFileExtension;
|
|
||||||
} catch(e) {
|
|
||||||
deferred.reject("SIGNATURE_PATH_INVALID");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let sRequestChannel = NetUtil.newChannel({
|
|
||||||
uri: signatureURL,
|
|
||||||
loadingPrincipal: principal,
|
|
||||||
contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER}
|
|
||||||
).QueryInterface(Ci.nsIHttpChannel);
|
|
||||||
sRequestChannel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
|
|
||||||
sRequestChannel.notificationCallbacks =
|
|
||||||
AppsUtils.createLoadContext(aAppId, false);
|
|
||||||
let getAsyncFetchCallback = (resolve, reject) =>
|
|
||||||
(aInputStream, aResult) => {
|
|
||||||
if (!Components.isSuccessCode(aResult)) {
|
|
||||||
debug("Failed to download file");
|
|
||||||
reject("MANIFEST_FILE_UNAVAILABLE");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
resolve(aInputStream);
|
|
||||||
};
|
|
||||||
|
|
||||||
Promise.all([
|
|
||||||
new Promise((resolve, reject) => {
|
|
||||||
NetUtil.asyncFetch(mRequestChannel,
|
|
||||||
getAsyncFetchCallback(resolve, reject));
|
|
||||||
}),
|
|
||||||
new Promise((resolve, reject) => {
|
|
||||||
NetUtil.asyncFetch(sRequestChannel,
|
|
||||||
getAsyncFetchCallback(resolve, reject));
|
|
||||||
})
|
|
||||||
]).then(([aManifestStream, aSignatureStream]) => {
|
|
||||||
this._verifySignedFile(aManifestStream, aSignatureStream, certDb)
|
|
||||||
.then(deferred.resolve, deferred.reject);
|
|
||||||
}, deferred.reject);
|
|
||||||
|
|
||||||
return deferred.promise;
|
|
||||||
},
|
|
||||||
|
|
||||||
verifyManifest: function(aApp, aAppId, aManifest) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
// sanity check on manifest host's CA (proper CA check with
|
|
||||||
// pinning is done by regular networking code)
|
|
||||||
if (!this.isHostPinned(aApp.manifestURL)) {
|
|
||||||
reject("TRUSTED_APPLICATION_HOST_CERTIFICATE_INVALID");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!this.verifyCSPWhiteList(aManifest.csp)) {
|
|
||||||
reject("TRUSTED_APPLICATION_WHITELIST_VALIDATION_FAILED");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.verifySignedManifest(aApp, aAppId).then(resolve, reject);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -85,9 +85,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "ScriptPreloader",
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "Langpacks",
|
XPCOMUtils.defineLazyModuleGetter(this, "Langpacks",
|
||||||
"resource://gre/modules/Langpacks.jsm");
|
"resource://gre/modules/Langpacks.jsm");
|
||||||
|
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "TrustedHostedAppsUtils",
|
|
||||||
"resource://gre/modules/TrustedHostedAppsUtils.jsm");
|
|
||||||
|
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "ImportExport",
|
XPCOMUtils.defineLazyModuleGetter(this, "ImportExport",
|
||||||
"resource://gre/modules/ImportExport.jsm");
|
"resource://gre/modules/ImportExport.jsm");
|
||||||
|
|
||||||
|
@ -191,7 +188,6 @@ this.DOMApplicationRegistry = {
|
||||||
get kPackaged() "packaged",
|
get kPackaged() "packaged",
|
||||||
get kHosted() "hosted",
|
get kHosted() "hosted",
|
||||||
get kHostedAppcache() "hosted-appcache",
|
get kHostedAppcache() "hosted-appcache",
|
||||||
get kTrustedHosted() "hosted-trusted",
|
|
||||||
|
|
||||||
// Path to the webapps.json file where we store the registry data.
|
// Path to the webapps.json file where we store the registry data.
|
||||||
appsFile: null,
|
appsFile: null,
|
||||||
|
@ -466,9 +462,7 @@ this.DOMApplicationRegistry = {
|
||||||
} else {
|
} else {
|
||||||
// Hosted apps, can be appcached or not.
|
// Hosted apps, can be appcached or not.
|
||||||
let kind = this.kHosted;
|
let kind = this.kHosted;
|
||||||
if (aManifest.type == "trusted") {
|
if (aManifest.appcache_path) {
|
||||||
kind = this.kTrustedHosted;
|
|
||||||
} else if (aManifest.appcache_path) {
|
|
||||||
kind = this.kHostedAppcache;
|
kind = this.kHostedAppcache;
|
||||||
}
|
}
|
||||||
return kind;
|
return kind;
|
||||||
|
@ -1590,24 +1584,6 @@ this.DOMApplicationRegistry = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if launching trusted hosted app
|
|
||||||
if (this.kTrustedHosted == app.kind) {
|
|
||||||
debug("Launching Trusted Hosted App!");
|
|
||||||
// sanity check on manifest host's CA
|
|
||||||
// (proper CA check with pinning is done by regular networking code)
|
|
||||||
if (!TrustedHostedAppsUtils.isHostPinned(aManifestURL)) {
|
|
||||||
debug("Trusted App Host certificate Not OK");
|
|
||||||
aOnFailure("TRUSTED_APPLICATION_HOST_CERTIFICATE_INVALID");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
debug("Trusted App Host pins exist");
|
|
||||||
if (!TrustedHostedAppsUtils.verifyCSPWhiteList(app.csp)) {
|
|
||||||
aOnFailure("TRUSTED_APPLICATION_WHITELIST_VALIDATION_FAILED");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We have to clone the app object as nsIDOMApplication objects are
|
// We have to clone the app object as nsIDOMApplication objects are
|
||||||
// stringified as an empty object. (see bug 830376)
|
// stringified as an empty object. (see bug 830376)
|
||||||
let appClone = AppsUtils.cloneAppObject(app);
|
let appClone = AppsUtils.cloneAppObject(app);
|
||||||
|
@ -1929,9 +1905,7 @@ this.DOMApplicationRegistry = {
|
||||||
|
|
||||||
startOfflineCacheDownload: function(aManifest, aApp, aProfileDir, aIsUpdate) {
|
startOfflineCacheDownload: function(aManifest, aApp, aProfileDir, aIsUpdate) {
|
||||||
debug("startOfflineCacheDownload " + aApp.id + " " + aApp.kind);
|
debug("startOfflineCacheDownload " + aApp.id + " " + aApp.kind);
|
||||||
if ((aApp.kind !== this.kHostedAppcache &&
|
if (aApp.kind !== this.kHostedAppcache || !aManifest.appcache_path) {
|
||||||
aApp.kind !== this.kTrustedHosted) ||
|
|
||||||
!aManifest.appcache_path) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
debug("startOfflineCacheDownload " + aManifest.appcache_path);
|
debug("startOfflineCacheDownload " + aManifest.appcache_path);
|
||||||
|
@ -2072,8 +2046,7 @@ this.DOMApplicationRegistry = {
|
||||||
|
|
||||||
if (onlyCheckAppCache) {
|
if (onlyCheckAppCache) {
|
||||||
// Bail out for packaged apps & hosted apps without appcache.
|
// Bail out for packaged apps & hosted apps without appcache.
|
||||||
if (aApp.kind !== this.kHostedAppcache &&
|
if (aApp.kind !== this.kHostedAppcache) {
|
||||||
aApp.kind !== this.kTrustedHosted) {
|
|
||||||
sendError("NOT_UPDATABLE");
|
sendError("NOT_UPDATABLE");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2187,16 +2160,7 @@ this.DOMApplicationRegistry = {
|
||||||
|
|
||||||
// For hosted apps and hosted apps with appcache, use the
|
// For hosted apps and hosted apps with appcache, use the
|
||||||
// manifest "as is".
|
// manifest "as is".
|
||||||
if (this.kTrustedHosted !== this.appKind(app, manifest)) {
|
this.updateHostedApp(aData, id, app, oldManifest, manifest);
|
||||||
this.updateHostedApp(aData, id, app, oldManifest, manifest);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For trusted hosted apps, verify the manifest before
|
|
||||||
// installation.
|
|
||||||
TrustedHostedAppsUtils.verifyManifest(app, id, manifest)
|
|
||||||
.then(() => this.updateHostedApp(aData, id, app, oldManifest, manifest),
|
|
||||||
sendError);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (xhr.status == 304) {
|
} else if (xhr.status == 304) {
|
||||||
|
@ -2375,9 +2339,7 @@ this.DOMApplicationRegistry = {
|
||||||
this.webapps[aId] = aApp;
|
this.webapps[aId] = aApp;
|
||||||
yield this._saveApps();
|
yield this._saveApps();
|
||||||
|
|
||||||
if ((aApp.kind !== this.kHostedAppcache &&
|
if (aApp.kind !== this.kHostedAppcache || !aApp.manifest.appcache_path) {
|
||||||
aApp.kind !== this.kTrustedHosted) ||
|
|
||||||
!aApp.manifest.appcache_path) {
|
|
||||||
MessageBroadcaster.broadcastMessage("Webapps:UpdateState", {
|
MessageBroadcaster.broadcastMessage("Webapps:UpdateState", {
|
||||||
app: aApp,
|
app: aApp,
|
||||||
manifest: aApp.manifest,
|
manifest: aApp.manifest,
|
||||||
|
@ -2533,12 +2495,7 @@ this.DOMApplicationRegistry = {
|
||||||
if (app.manifest) {
|
if (app.manifest) {
|
||||||
if (checkManifest()) {
|
if (checkManifest()) {
|
||||||
debug("Installed manifest check OK");
|
debug("Installed manifest check OK");
|
||||||
if (this.kTrustedHosted !== this.appKind(app, app.manifest)) {
|
installApp();
|
||||||
installApp();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
TrustedHostedAppsUtils.verifyManifest(aData.app, aData.appId, app.manifest)
|
|
||||||
.then(installApp, sendError);
|
|
||||||
} else {
|
} else {
|
||||||
debug("Installed manifest check failed");
|
debug("Installed manifest check failed");
|
||||||
// checkManifest() sends error before return
|
// checkManifest() sends error before return
|
||||||
|
@ -2566,14 +2523,7 @@ this.DOMApplicationRegistry = {
|
||||||
if (checkManifest()) {
|
if (checkManifest()) {
|
||||||
debug("Downloaded manifest check OK");
|
debug("Downloaded manifest check OK");
|
||||||
app.etag = xhr.getResponseHeader("Etag");
|
app.etag = xhr.getResponseHeader("Etag");
|
||||||
if (this.kTrustedHosted !== this.appKind(app, app.manifest)) {
|
installApp();
|
||||||
installApp();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
debug("App kind: " + this.kTrustedHosted);
|
|
||||||
TrustedHostedAppsUtils.verifyManifest(aData.app, aData.appId, app.manifest)
|
|
||||||
.then(installApp, sendError);
|
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
debug("Downloaded manifest check failed");
|
debug("Downloaded manifest check failed");
|
||||||
|
@ -2832,9 +2782,6 @@ this.DOMApplicationRegistry = {
|
||||||
aNewApp.appStatus || Ci.nsIPrincipal.APP_STATUS_INSTALLED;
|
aNewApp.appStatus || Ci.nsIPrincipal.APP_STATUS_INSTALLED;
|
||||||
|
|
||||||
let usesAppcache = appObject.kind == this.kHostedAppcache;
|
let usesAppcache = appObject.kind == this.kHostedAppcache;
|
||||||
if (appObject.kind == this.kTrustedHosted && aManifest.appcache_path) {
|
|
||||||
usesAppcache = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (usesAppcache) {
|
if (usesAppcache) {
|
||||||
appObject.installState = "pending";
|
appObject.installState = "pending";
|
||||||
|
@ -2848,8 +2795,7 @@ this.DOMApplicationRegistry = {
|
||||||
appObject.downloading = true;
|
appObject.downloading = true;
|
||||||
appObject.downloadSize = aLocaleManifest.size;
|
appObject.downloadSize = aLocaleManifest.size;
|
||||||
appObject.readyToApplyDownload = false;
|
appObject.readyToApplyDownload = false;
|
||||||
} else if (appObject.kind == this.kHosted ||
|
} else if (appObject.kind == this.kHosted) {
|
||||||
appObject.kind == this.kTrustedHosted) {
|
|
||||||
appObject.installState = "installed";
|
appObject.installState = "installed";
|
||||||
appObject.downloadAvailable = false;
|
appObject.downloadAvailable = false;
|
||||||
appObject.downloading = false;
|
appObject.downloading = false;
|
||||||
|
@ -3030,9 +2976,7 @@ this.DOMApplicationRegistry = {
|
||||||
|
|
||||||
let dontNeedNetwork = false;
|
let dontNeedNetwork = false;
|
||||||
|
|
||||||
if ((appObject.kind == this.kHostedAppcache ||
|
if (appObject.kind == this.kHostedAppcache && manifest.appcache_path) {
|
||||||
appObject.kind == this.kTrustedHosted) &&
|
|
||||||
manifest.appcache_path) {
|
|
||||||
this.queuedDownload[app.manifestURL] = {
|
this.queuedDownload[app.manifestURL] = {
|
||||||
manifest: manifest,
|
manifest: manifest,
|
||||||
app: appObject,
|
app: appObject,
|
||||||
|
|
|
@ -48,7 +48,6 @@ EXTRA_PP_JS_MODULES += [
|
||||||
'InterAppCommService.jsm',
|
'InterAppCommService.jsm',
|
||||||
'OperatorApps.jsm',
|
'OperatorApps.jsm',
|
||||||
'ScriptPreloader.jsm',
|
'ScriptPreloader.jsm',
|
||||||
'TrustedHostedAppsUtils.jsm',
|
|
||||||
'Webapps.jsm',
|
'Webapps.jsm',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ support-files =
|
||||||
[test_apps_service.xul]
|
[test_apps_service.xul]
|
||||||
[test_bug_945152.html]
|
[test_bug_945152.html]
|
||||||
skip-if = os != 'linux'
|
skip-if = os != 'linux'
|
||||||
[test_tha_utils.html]
|
|
||||||
[test_manifest_helper.xul]
|
[test_manifest_helper.xul]
|
||||||
[test_operator_app_install.js]
|
[test_operator_app_install.js]
|
||||||
[test_operator_app_install.xul]
|
[test_operator_app_install.xul]
|
||||||
|
|
|
@ -14,8 +14,7 @@ function makeResource(templatePath, version, apptype, role) {
|
||||||
|
|
||||||
// Hack - This is necessary to make the tests pass, but hbambas says it
|
// Hack - This is necessary to make the tests pass, but hbambas says it
|
||||||
// shouldn't be necessary. Comment it out and watch the tests fail.
|
// shouldn't be necessary. Comment it out and watch the tests fail.
|
||||||
if (templatePath == gAppTemplatePath &&
|
if (templatePath == gAppTemplatePath && apptype == 'cached') {
|
||||||
(apptype == 'cached' || apptype == 'trusted')) {
|
|
||||||
res = res.replace('<html>', '<html manifest="file_app.sjs?apptype=' + apptype + '&getappcache=true">');
|
res = res.replace('<html>', '<html manifest="file_app.sjs?apptype=' + apptype + '&getappcache=true">');
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
@ -49,7 +48,7 @@ function handleRequest(request, response) {
|
||||||
|
|
||||||
// Get the app type.
|
// Get the app type.
|
||||||
var apptype = query.apptype;
|
var apptype = query.apptype;
|
||||||
if (apptype != 'hosted' && apptype != 'cached' && apptype != 'widget' && apptype != 'invalidWidget' && apptype != 'trusted')
|
if (apptype != 'hosted' && apptype != 'cached' && apptype != 'widget' && apptype != 'invalidWidget')
|
||||||
throw "Invalid app type: " + apptype;
|
throw "Invalid app type: " + apptype;
|
||||||
|
|
||||||
var role = query.role;
|
var role = query.role;
|
||||||
|
@ -90,7 +89,7 @@ function handleRequest(request, response) {
|
||||||
//
|
//
|
||||||
// NB: Among other reasons, we use the same sjs file here so that the version
|
// NB: Among other reasons, we use the same sjs file here so that the version
|
||||||
// state is shared.
|
// state is shared.
|
||||||
if ((apptype == 'cached' || apptype == 'trusted') &&
|
if ((apptype == 'cached') &&
|
||||||
'getappcache' in query) {
|
'getappcache' in query) {
|
||||||
response.setHeader("Content-Type", "text/cache-manifest", false);
|
response.setHeader("Content-Type", "text/cache-manifest", false);
|
||||||
response.write(makeResource(gAppcacheTemplatePath, version, apptype, role));
|
response.write(makeResource(gAppcacheTemplatePath, version, apptype, role));
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
{
|
|
||||||
"type": "trusted",
|
|
||||||
"name": "Really Rapid Release (trusted)",
|
|
||||||
"description": "Updated even faster than <a href='http://mozilla.org'>Firefox</a>, just to annoy slashdotters.",
|
|
||||||
"launch_path": "/tests/dom/apps/tests/file_app.sjs?apptype=trusted",
|
|
||||||
"icons": {
|
|
||||||
"128": "ICONTOKEN"
|
|
||||||
},
|
|
||||||
"role": "ROLE"
|
|
||||||
}
|
|
|
@ -18,7 +18,6 @@ support-files =
|
||||||
file_hosted_certified.webapp^headers^
|
file_hosted_certified.webapp^headers^
|
||||||
file_manifest.json
|
file_manifest.json
|
||||||
file_manifest.json^headers^
|
file_manifest.json^headers^
|
||||||
file_trusted_app.template.webapp
|
|
||||||
file_invalidWidget_app.template.webapp
|
file_invalidWidget_app.template.webapp
|
||||||
file_packaged_app.sjs
|
file_packaged_app.sjs
|
||||||
file_packaged_app.template.html
|
file_packaged_app.template.html
|
||||||
|
|
|
@ -17,13 +17,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=826058
|
||||||
var gBaseURL = 'http://test/tests/dom/apps/tests/';
|
var gBaseURL = 'http://test/tests/dom/apps/tests/';
|
||||||
var gHostedManifestURL = gBaseURL + 'file_app.sjs?apptype=hosted&getmanifest=true';
|
var gHostedManifestURL = gBaseURL + 'file_app.sjs?apptype=hosted&getmanifest=true';
|
||||||
var gCachedManifestURL = gBaseURL + 'file_app.sjs?apptype=cached&getmanifest=true';
|
var gCachedManifestURL = gBaseURL + 'file_app.sjs?apptype=cached&getmanifest=true';
|
||||||
var gTrustedManifestURL = gBaseURL + 'file_app.sjs?apptype=trusted&getmanifest=true';
|
|
||||||
var gGenerator;
|
var gGenerator;
|
||||||
// We need to set the trusted hosted app csp pref since it's only in
|
// We need to set the trusted hosted app csp pref since it's only in
|
||||||
// b2g.js for now.
|
// b2g.js for now.
|
||||||
function setCSPPrefs() {
|
function setCSPPrefs() {
|
||||||
SpecialPowers.pushPrefEnv({'set':[["security.apps.trusted.CSP.default",
|
SpecialPowers.pushPrefEnv({'set':[["dom.mozBrowserFramesEnabled",true]]},
|
||||||
"default-src *; object-src 'none'"], ["dom.mozBrowserFramesEnabled",true]]},
|
|
||||||
function() { gGenerator = runTest(); gGenerator.next(); });
|
function() { gGenerator = runTest(); gGenerator.next(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,54 +188,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=826058
|
||||||
request.onsuccess = continueTest;
|
request.onsuccess = continueTest;
|
||||||
yield undefined;
|
yield undefined;
|
||||||
info("Uninstalled hosted appcache app");
|
info("Uninstalled hosted appcache app");
|
||||||
|
|
||||||
/**
|
|
||||||
* DISABLED FOR NOW UNTIL WE CAN TEST PINNING PROPERLY
|
|
||||||
*/
|
|
||||||
// Install the trusted app.
|
|
||||||
/*setAppVersion(4, continueTest);
|
|
||||||
yield undefined;
|
|
||||||
ok(true, "Installing trusted app");
|
|
||||||
var request = navigator.mozApps.install(gTrustedManifestURL);
|
|
||||||
request.onerror = mozAppsError;
|
|
||||||
request.onsuccess = continueTest;
|
|
||||||
yield undefined;
|
|
||||||
var app = request.result;
|
|
||||||
ok(app, "App is non-null");
|
|
||||||
if (app.installState == "pending") {
|
|
||||||
ok(true, "App is pending. Waiting for progress");
|
|
||||||
app.onprogress = function() ok(true, "Got download progress");
|
|
||||||
app.ondownloadsuccess = continueTest;
|
|
||||||
app.ondownloaderror = mozAppsError;
|
|
||||||
yield undefined;
|
|
||||||
}
|
|
||||||
is(app.installState, "installed", "Trusted App is installed");
|
|
||||||
is(app.manifest.type, "trusted", "App is trusted");
|
|
||||||
*/
|
|
||||||
// Check the cached app.
|
|
||||||
/*checkAppState(app, true, 4, continueTest);
|
|
||||||
yield undefined;*/
|
|
||||||
|
|
||||||
// Check for updates. The current infrastructure always returns a new appcache
|
|
||||||
// manifest, so there should always be an update.
|
|
||||||
/*var lastCheck = app.lastUpdateCheck;
|
|
||||||
ok(true, "Setting callbacks");
|
|
||||||
app.ondownloadapplied = function() ok(true, "downloadapplied fired.");
|
|
||||||
app.ondownloadavailable = function() ok(false, "downloadavailable fired");
|
|
||||||
ok(true, "Checking for updates");
|
|
||||||
var request = app.checkForUpdate();
|
|
||||||
request.onerror = mozAppsError;
|
|
||||||
request.onsuccess = continueTest;
|
|
||||||
yield undefined;
|
|
||||||
todo(app.lastUpdateCheck > lastCheck, "lastUpdateCheck updated appropriately");*/
|
|
||||||
|
|
||||||
|
|
||||||
// Uninstall the app.
|
|
||||||
/*request = navigator.mozApps.mgmt.uninstall(app);
|
|
||||||
request.onerror = mozAppsError;
|
|
||||||
request.onsuccess = continueTest;
|
|
||||||
yield undefined;
|
|
||||||
info("Uninstalled trusted app");*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function setAppVersion(version, cb) {
|
function setAppVersion(version, cb) {
|
||||||
|
|
|
@ -1,237 +0,0 @@
|
||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>Test for Trusted Hosted Apps Utils</title>
|
|
||||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
|
|
||||||
|
|
||||||
<script type="application/javascript;version=1.7">
|
|
||||||
Components.utils.import("resource://gre/modules/TrustedHostedAppsUtils.jsm");
|
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
|
|
||||||
let tests = [{
|
|
||||||
key: "getCSPWhiteList with no argument",
|
|
||||||
func: function test1() {
|
|
||||||
let cspWhiteList = TrustedHostedAppsUtils.getCSPWhiteList();
|
|
||||||
ok(!cspWhiteList.valid, "Should be invalid");
|
|
||||||
is(cspWhiteList.list.length, 0, "List should be empty");
|
|
||||||
nextTest();
|
|
||||||
}
|
|
||||||
},{
|
|
||||||
key: "getCSPWhiteList without style-src",
|
|
||||||
func: function test2() {
|
|
||||||
let cspWhiteList = TrustedHostedAppsUtils.getCSPWhiteList(
|
|
||||||
"script-src https://script.example.com; stylee-src https://style.example.com"
|
|
||||||
);
|
|
||||||
ok(!cspWhiteList.valid, "Should be invalid");
|
|
||||||
is(cspWhiteList.list.length, 0, "List should be empty");
|
|
||||||
nextTest();
|
|
||||||
}
|
|
||||||
},{
|
|
||||||
key: "getCSPWhiteList without script-src",
|
|
||||||
func: function test3() {
|
|
||||||
let cspWhiteList = TrustedHostedAppsUtils.getCSPWhiteList(
|
|
||||||
"script-source https://script.example.com; style-src https://style.example.com"
|
|
||||||
);
|
|
||||||
ok(!cspWhiteList.valid, "Should be invalid");
|
|
||||||
is(cspWhiteList.list.length, 0, "List should be empty");
|
|
||||||
nextTest();
|
|
||||||
}
|
|
||||||
},{
|
|
||||||
key: "getCSPWhiteList without source",
|
|
||||||
func: function test4() {
|
|
||||||
let cspWhiteList = TrustedHostedAppsUtils.getCSPWhiteList(
|
|
||||||
"script-src; style-src https://style.example.com"
|
|
||||||
);
|
|
||||||
ok(!cspWhiteList.valid, "Should be invalid");
|
|
||||||
is(cspWhiteList.list.length, 0, "List should be empty");
|
|
||||||
nextTest();
|
|
||||||
}
|
|
||||||
},{
|
|
||||||
key: "getCSPWhiteList working",
|
|
||||||
func: function test5() {
|
|
||||||
let cspWhiteList = TrustedHostedAppsUtils.getCSPWhiteList(
|
|
||||||
"script-src https://script.example.com; style-src https://style.example.com"
|
|
||||||
);
|
|
||||||
ok(cspWhiteList.valid, "Should be valid");
|
|
||||||
is(cspWhiteList.list.length, 2, "List should have two sources");
|
|
||||||
ok(cspWhiteList.list.every(aEl => ["https://script.example.com", "https://style.example.com"].indexOf(aEl) != -1), "Sources: " + cspWhiteList.list);
|
|
||||||
nextTest();
|
|
||||||
}
|
|
||||||
},{
|
|
||||||
key: "getCSPWhiteList working with duplicates",
|
|
||||||
func: function test6() {
|
|
||||||
let cspWhiteList = TrustedHostedAppsUtils.getCSPWhiteList(
|
|
||||||
"script-src https://script.example.com;" +
|
|
||||||
"style-src https://style.example.com;" +
|
|
||||||
"style-src https://style.example.com;" +
|
|
||||||
"style-src https://style.example.com;" +
|
|
||||||
"style-src https://style.example.com;"
|
|
||||||
);
|
|
||||||
ok(cspWhiteList.valid, "Should be valid");
|
|
||||||
is(cspWhiteList.list.length, 2, "List should have two sources");
|
|
||||||
ok(cspWhiteList.list.every(aEl => ["https://script.example.com", "https://style.example.com"].indexOf(aEl) != -1), "Sources: " + cspWhiteList.list);
|
|
||||||
nextTest();
|
|
||||||
}
|
|
||||||
},{
|
|
||||||
key: "getCSPWhiteList working with duplicates and many sources",
|
|
||||||
func: function test7() {
|
|
||||||
let cspWhiteList = TrustedHostedAppsUtils.getCSPWhiteList(
|
|
||||||
"script-src https://script.example.com https://script2.example.com;" +
|
|
||||||
"style-src https://style.example.com;" +
|
|
||||||
"style-src https://style.example.com https://script1.example.com;" +
|
|
||||||
"style-src https://style.example.com https://style2.example.com;" +
|
|
||||||
"style-src https://style3.example.com;"
|
|
||||||
);
|
|
||||||
ok(cspWhiteList.valid, "Should be valid");
|
|
||||||
is(cspWhiteList.list.length, 6, "List should have 6 sources");
|
|
||||||
ok(cspWhiteList.list.every(aEl => ["https://script.example.com",
|
|
||||||
"https://script1.example.com",
|
|
||||||
"https://script2.example.com",
|
|
||||||
"https://style.example.com",
|
|
||||||
"https://style2.example.com",
|
|
||||||
"https://style3.example.com"].indexOf(aEl) != -1),
|
|
||||||
"Sources: " + cspWhiteList.list);
|
|
||||||
nextTest();
|
|
||||||
}
|
|
||||||
},{
|
|
||||||
key: "getCSPWhiteList only adds sources from required directives",
|
|
||||||
func: function test8() {
|
|
||||||
let cspWhiteList = TrustedHostedAppsUtils.getCSPWhiteList(
|
|
||||||
"script-src https://script.example.com https://script2.example.com;" +
|
|
||||||
"style-src https://style.example.com;" +
|
|
||||||
"img-src https://img.example.com;" +
|
|
||||||
"audio-src https://audio.example.com https://audio2.example.com;" +
|
|
||||||
"video-src https://video.example.com;" +
|
|
||||||
"default-src *;" +
|
|
||||||
"media-src http://media.example.com;" +
|
|
||||||
"child-src http://child.example.com;" +
|
|
||||||
"frame-src http://frame.example.com;" +
|
|
||||||
"frame-ancestrs http://frame-a.example.com;" +
|
|
||||||
"font-src http://font.example.com;" +
|
|
||||||
"connect-src http://connect.example.com;"
|
|
||||||
);
|
|
||||||
ok(cspWhiteList.valid, "Should be valid");
|
|
||||||
is(cspWhiteList.list.length, 3, "List should have 3 sources");
|
|
||||||
ok(cspWhiteList.list.every(aEl => ["https://script.example.com",
|
|
||||||
"https://script2.example.com",
|
|
||||||
"https://style.example.com"].indexOf(aEl) != -1),
|
|
||||||
"Sources: " + cspWhiteList.list);
|
|
||||||
nextTest();
|
|
||||||
}
|
|
||||||
},{
|
|
||||||
key: "getCSPWhiteList allows 'self' but doesn't add it",
|
|
||||||
func: function test9() {
|
|
||||||
let cspWhiteList = TrustedHostedAppsUtils.getCSPWhiteList(
|
|
||||||
"script-src 'self';" +
|
|
||||||
"style-src 'self'"
|
|
||||||
);
|
|
||||||
ok(cspWhiteList.valid, "Should be valid");
|
|
||||||
is(cspWhiteList.list.length, 0, "List should have no source");
|
|
||||||
nextTest();
|
|
||||||
}
|
|
||||||
},{
|
|
||||||
key: "getCSPWhiteList allows *",
|
|
||||||
func: function test10() {
|
|
||||||
let cspWhiteList = TrustedHostedAppsUtils.getCSPWhiteList(
|
|
||||||
"script-src *;" +
|
|
||||||
"style-src https://style.example.com"
|
|
||||||
);
|
|
||||||
ok(cspWhiteList.valid, "Should be valid");
|
|
||||||
is(cspWhiteList.list.length, 2, "List should have 2 sources");
|
|
||||||
nextTest();
|
|
||||||
}
|
|
||||||
},{
|
|
||||||
key: "isHostPinned doesn't allow *",
|
|
||||||
func: function test11() {
|
|
||||||
let isHostPinned = TrustedHostedAppsUtils.isHostPinned("*");
|
|
||||||
ok(!isHostPinned, "Should not be pinned");
|
|
||||||
nextTest();
|
|
||||||
}
|
|
||||||
},{
|
|
||||||
key: "isHostPinned doesn't allow http urls",
|
|
||||||
func: function test12() {
|
|
||||||
let isHostPinned = TrustedHostedAppsUtils.isHostPinned("http://example.com");
|
|
||||||
ok(!isHostPinned, "Should not be pinned:(" + isHostPinned + ") http://example.com");
|
|
||||||
nextTest();
|
|
||||||
}
|
|
||||||
},{
|
|
||||||
key: "isHostPinned doesn't allow shema-less urls",
|
|
||||||
func: function test13() {
|
|
||||||
let isHostPinned = TrustedHostedAppsUtils.isHostPinned("example.com");
|
|
||||||
ok(!isHostPinned, "Should not be pinned:(" + isHostPinned + ") example.com");
|
|
||||||
nextTest();
|
|
||||||
}
|
|
||||||
},{
|
|
||||||
key: "isHostPinned doesn't allow 'unsafe-eval'",
|
|
||||||
func: function test14() {
|
|
||||||
let isHostPinned = TrustedHostedAppsUtils.isHostPinned("'unsafe-eval'");
|
|
||||||
ok(!isHostPinned, "Should not be pinned:(" + isHostPinned + ") 'unsafe-eval'");
|
|
||||||
nextTest();
|
|
||||||
}
|
|
||||||
},{
|
|
||||||
key: "isHostPinned doesn't allow 'unsafe-inline'",
|
|
||||||
func: function test15() {
|
|
||||||
let isHostPinned = TrustedHostedAppsUtils.isHostPinned("'unsafe-inline'");
|
|
||||||
ok(!isHostPinned, "Should not be pinned:(" + isHostPinned + ") 'unsafe-inline'");
|
|
||||||
nextTest();
|
|
||||||
}
|
|
||||||
},{
|
|
||||||
key: "isHostPinned doesn't allow foobar",
|
|
||||||
func: function test16() {
|
|
||||||
let isHostPinned = TrustedHostedAppsUtils.isHostPinned("foobar");
|
|
||||||
ok(!isHostPinned, "Should not be pinned:(" + isHostPinned + ") foobar");
|
|
||||||
nextTest();
|
|
||||||
}
|
|
||||||
},{
|
|
||||||
key: "isHostPinned doesn't allow https://www.example.com:*",
|
|
||||||
func: function test17() {
|
|
||||||
let isHostPinned = TrustedHostedAppsUtils.isHostPinned("https://example.com:*");
|
|
||||||
ok(!isHostPinned, "Should not be pinned:(" + isHostPinned + ") https://example.com:*");
|
|
||||||
nextTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
},{
|
|
||||||
key: "isHostPinned doesn't allow https://*.example.com",
|
|
||||||
func: function test18() {
|
|
||||||
let isHostPinned = TrustedHostedAppsUtils.isHostPinned("https://*.example.com");
|
|
||||||
ok(!isHostPinned, "Should not be pinned:(" + isHostPinned + ") https://*.example.com");
|
|
||||||
nextTest();
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
|
|
||||||
let testGenerator = function _testGenerator() {
|
|
||||||
for (let i = 0; i < tests.length; ++i) {
|
|
||||||
yield tests[i];
|
|
||||||
}
|
|
||||||
}();
|
|
||||||
|
|
||||||
let nextTest = () => {
|
|
||||||
try {
|
|
||||||
let t = testGenerator.next();
|
|
||||||
info("test: " + t.key);
|
|
||||||
t.func();
|
|
||||||
} catch(e) {
|
|
||||||
if (e instanceof StopIteration) {
|
|
||||||
SimpleTest.finish();
|
|
||||||
} else {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", function () {
|
|
||||||
nextTest();
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<p id="display"></p>
|
|
||||||
<div id="content" style="display: none"></div>
|
|
||||||
<pre id="test"></pre>
|
|
||||||
<div id="container"></div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -229,12 +229,12 @@ this.SystemMessagePermissionsChecker = {
|
||||||
aManifestURL,
|
aManifestURL,
|
||||||
aOrigin,
|
aOrigin,
|
||||||
aManifest) {
|
aManifest) {
|
||||||
// Test if the launch path of the app has the right permission.
|
// Test if the launch path of the app has the right permission.
|
||||||
let newManifest = new ManifestHelper(aManifest, aOrigin, aManifestURL);
|
let newManifest = new ManifestHelper(aManifest, aOrigin, aManifestURL);
|
||||||
let launchUrl = newManifest.fullLaunchPath();
|
let launchUrl = newManifest.fullLaunchPath();
|
||||||
return this.isSystemMessagePermittedToSend(aSysMsgName,
|
return this.isSystemMessagePermittedToSend(aSysMsgName,
|
||||||
launchUrl,
|
launchUrl,
|
||||||
aManifestURL);
|
aManifestURL);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -84,16 +84,6 @@ AppTrustDomain::SetTrustedRoot(AppTrustedRoot trustedRoot)
|
||||||
trustedDER.len = mozilla::ArrayLength(xpcshellRoot);
|
trustedDER.len = mozilla::ArrayLength(xpcshellRoot);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nsIX509CertDB::TrustedHostedAppPublicRoot:
|
|
||||||
trustedDER.data = const_cast<uint8_t*>(trustedAppPublicRoot);
|
|
||||||
trustedDER.len = mozilla::ArrayLength(trustedAppPublicRoot);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case nsIX509CertDB::TrustedHostedAppTestRoot:
|
|
||||||
trustedDER.data = const_cast<uint8_t*>(trustedAppTestRoot);
|
|
||||||
trustedDER.len = mozilla::ArrayLength(trustedAppTestRoot);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case nsIX509CertDB::AddonsPublicRoot:
|
case nsIX509CertDB::AddonsPublicRoot:
|
||||||
trustedDER.data = const_cast<uint8_t*>(addonsPublicRoot);
|
trustedDER.data = const_cast<uint8_t*>(addonsPublicRoot);
|
||||||
trustedDER.len = mozilla::ArrayLength(addonsPublicRoot);
|
trustedDER.len = mozilla::ArrayLength(addonsPublicRoot);
|
||||||
|
|
|
@ -46,7 +46,7 @@ interface nsIVerifySignedManifestCallback : nsISupports
|
||||||
* This represents a service to access and manipulate
|
* This represents a service to access and manipulate
|
||||||
* X.509 certificates stored in a database.
|
* X.509 certificates stored in a database.
|
||||||
*/
|
*/
|
||||||
[scriptable, uuid(fbe2a0c8-ec51-4ea4-80b3-e16793141967)]
|
[scriptable, uuid(c9fdec46-5c4c-4b1d-a0ca-c2bc10151b69)]
|
||||||
interface nsIX509CertDB : nsISupports {
|
interface nsIX509CertDB : nsISupports {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -316,10 +316,8 @@ interface nsIX509CertDB : nsISupports {
|
||||||
const AppTrustedRoot AppMarketplaceDevReviewersRoot = 4;
|
const AppTrustedRoot AppMarketplaceDevReviewersRoot = 4;
|
||||||
const AppTrustedRoot AppMarketplaceStageRoot = 5;
|
const AppTrustedRoot AppMarketplaceStageRoot = 5;
|
||||||
const AppTrustedRoot AppXPCShellRoot = 6;
|
const AppTrustedRoot AppXPCShellRoot = 6;
|
||||||
const AppTrustedRoot TrustedHostedAppPublicRoot = 7;
|
const AppTrustedRoot AddonsPublicRoot = 7;
|
||||||
const AppTrustedRoot TrustedHostedAppTestRoot = 8;
|
const AppTrustedRoot AddonsStageRoot = 8;
|
||||||
const AppTrustedRoot AddonsPublicRoot = 9;
|
|
||||||
const AppTrustedRoot AddonsStageRoot = 10;
|
|
||||||
void openSignedAppFileAsync(in AppTrustedRoot trustedRoot,
|
void openSignedAppFileAsync(in AppTrustedRoot trustedRoot,
|
||||||
in nsIFile aJarFile,
|
in nsIFile aJarFile,
|
||||||
in nsIOpenSignedAppFileCallback callback);
|
in nsIOpenSignedAppFileCallback callback);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче