зеркало из 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.
|
||||
// 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");
|
||||
// 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
|
||||
// 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) {
|
||||
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));
|
||||
} else if (this.type == "hosted" &&
|
||||
["certified", "privileged"].indexOf(appType) !== -1) {
|
||||
|
|
|
@ -26,8 +26,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "appsService",
|
|||
"@mozilla.org/AppsService;1",
|
||||
"nsIAppsService");
|
||||
|
||||
// Shared code for AppsServiceChild.jsm, TrustedHostedAppsUtils.jsm,
|
||||
// Webapps.jsm and Webapps.js
|
||||
// Shared code for AppsServiceChild.jsm, Webapps.jsm and Webapps.js
|
||||
|
||||
this.EXPORTED_SYMBOLS =
|
||||
["AppsUtils", "ManifestHelper", "isAbsoluteURI", "mozIApplication"];
|
||||
|
@ -300,9 +299,7 @@ this.AppsUtils = {
|
|||
return Services.prefs.getCharPref("security.apps.privileged.CSP.default");
|
||||
break;
|
||||
case Ci.nsIPrincipal.APP_STATUS_INSTALLED:
|
||||
return app.kind == "hosted-trusted"
|
||||
? Services.prefs.getCharPref("security.apps.trusted.CSP.default")
|
||||
: "";
|
||||
return "";
|
||||
break;
|
||||
}
|
||||
} catch(e) {}
|
||||
|
@ -605,7 +602,6 @@ this.AppsUtils = {
|
|||
|
||||
switch(type) {
|
||||
case "web":
|
||||
case "trusted":
|
||||
return Ci.nsIPrincipal.APP_STATUS_INSTALLED;
|
||||
case "privileged":
|
||||
return Ci.nsIPrincipal.APP_STATUS_PRIVILEGED;
|
||||
|
|
|
@ -107,9 +107,6 @@ this.PermissionsInstaller = {
|
|||
break;
|
||||
case Ci.nsIPrincipal.APP_STATUS_INSTALLED:
|
||||
appStatus = "app";
|
||||
if (aApp.kind == "hosted-trusted") {
|
||||
appStatus = "trusted";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Cannot determine app type, abort install by throwing an error.
|
||||
|
|
|
@ -35,153 +35,129 @@ const PROMPT_ACTION = Ci.nsIPermissionManager.PROMPT_ACTION;
|
|||
|
||||
this.PermissionsTable = { geolocation: {
|
||||
app: PROMPT_ACTION,
|
||||
trusted: PROMPT_ACTION,
|
||||
privileged: PROMPT_ACTION,
|
||||
certified: PROMPT_ACTION
|
||||
},
|
||||
"geolocation-noprompt": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION,
|
||||
substitute: ["geolocation"]
|
||||
},
|
||||
camera: {
|
||||
app: DENY_ACTION,
|
||||
trusted: PROMPT_ACTION,
|
||||
privileged: PROMPT_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
alarms: {
|
||||
app: ALLOW_ACTION,
|
||||
trusted: ALLOW_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"tcp-socket": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"udp-socket": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"network-events": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
contacts: {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: PROMPT_ACTION,
|
||||
certified: ALLOW_ACTION,
|
||||
access: ["read", "write", "create"]
|
||||
},
|
||||
"device-storage:apps": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION,
|
||||
access: ["read"]
|
||||
},
|
||||
"device-storage:crashes": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION,
|
||||
access: ["read"]
|
||||
},
|
||||
"device-storage:pictures": {
|
||||
app: DENY_ACTION,
|
||||
trusted: PROMPT_ACTION,
|
||||
privileged: PROMPT_ACTION,
|
||||
certified: ALLOW_ACTION,
|
||||
access: ["read", "write", "create"]
|
||||
},
|
||||
"device-storage:videos": {
|
||||
app: DENY_ACTION,
|
||||
trusted: PROMPT_ACTION,
|
||||
privileged: PROMPT_ACTION,
|
||||
certified: ALLOW_ACTION,
|
||||
access: ["read", "write", "create"]
|
||||
},
|
||||
"device-storage:music": {
|
||||
app: DENY_ACTION,
|
||||
trusted: PROMPT_ACTION,
|
||||
privileged: PROMPT_ACTION,
|
||||
certified: ALLOW_ACTION,
|
||||
access: ["read", "write", "create"]
|
||||
},
|
||||
"device-storage:sdcard": {
|
||||
app: DENY_ACTION,
|
||||
trusted: PROMPT_ACTION,
|
||||
privileged: PROMPT_ACTION,
|
||||
certified: ALLOW_ACTION,
|
||||
access: ["read", "write", "create"]
|
||||
},
|
||||
sms: {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
telephony: {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
browser: {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"browser:universalxss": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
bluetooth: {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
mobileconnection: {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
mobilenetwork: {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
power: {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
push: {
|
||||
app: ALLOW_ACTION,
|
||||
trusted: ALLOW_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
settings: {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION,
|
||||
access: ["read", "write"],
|
||||
|
@ -192,287 +168,240 @@ this.PermissionsTable = { geolocation: {
|
|||
// handed out by SpecialPowers.
|
||||
"settings-clear": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: DENY_ACTION,
|
||||
additional: ["indexedDB-chrome-settings", "settings-api"]
|
||||
},
|
||||
permissions: {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
phonenumberservice: {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
fmradio: {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
attention: {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"global-clickthrough-overlay": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"moz-attention": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION,
|
||||
substitute: ["attention"]
|
||||
},
|
||||
"webapps-manage": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"homescreen-webapps-manage": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"backgroundservice": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"desktop-notification": {
|
||||
app: ALLOW_ACTION,
|
||||
trusted: ALLOW_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"networkstats-manage": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"resourcestats-manage": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"wifi-manage": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"systemXHR": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"voicemail": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"idle": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"time": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"embed-apps": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"embed-widgets": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"background-sensors": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
cellbroadcast: {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"audio-channel-normal": {
|
||||
app: ALLOW_ACTION,
|
||||
trusted: ALLOW_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"audio-channel-content": {
|
||||
app: ALLOW_ACTION,
|
||||
trusted: ALLOW_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"audio-channel-notification": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"audio-channel-alarm": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"audio-channel-system": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"audio-channel-telephony": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"moz-audio-channel-telephony": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION,
|
||||
substitute: ["audio-channel-telephony"]
|
||||
},
|
||||
"audio-channel-ringer": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"moz-audio-channel-ringer": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION,
|
||||
substitute: ["audio-channel-ringer"]
|
||||
},
|
||||
"audio-channel-publicnotification": {
|
||||
app: DENY_ACTION,
|
||||
trusted: ALLOW_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"open-remote-window": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"input": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"input-manage": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"wappush": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"audio-capture": {
|
||||
app: PROMPT_ACTION,
|
||||
trusted: PROMPT_ACTION,
|
||||
privileged: PROMPT_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"audio-capture:3gpp": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"nfc": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"nfc": {
|
||||
app: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"nfc-share": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"nfc-manager": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"nfc-hci-events": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"speaker-control": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"downloads": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"video-capture": {
|
||||
app: PROMPT_ACTION,
|
||||
trusted: PROMPT_ACTION,
|
||||
privileged: PROMPT_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"feature-detection": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"mobileid": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: PROMPT_ACTION,
|
||||
certified: PROMPT_ACTION
|
||||
},
|
||||
|
@ -481,33 +410,28 @@ this.PermissionsTable = { geolocation: {
|
|||
// of web prompt composed permissions in tests.
|
||||
"test-permission": {
|
||||
app: PROMPT_ACTION,
|
||||
trusted: PROMPT_ACTION,
|
||||
privileged: PROMPT_ACTION,
|
||||
certified: ALLOW_ACTION,
|
||||
access: ["read", "write", "create"]
|
||||
},
|
||||
"firefox-accounts": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"moz-firefox-accounts": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: PROMPT_ACTION,
|
||||
certified: ALLOW_ACTION,
|
||||
substitute: ["firefox-accounts"]
|
||||
},
|
||||
},
|
||||
"themeable": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"settings:wallpaper.image": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION,
|
||||
access: ["read", "write"],
|
||||
|
@ -515,67 +439,56 @@ this.PermissionsTable = { geolocation: {
|
|||
},
|
||||
"engineering-mode": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"tv": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"before-after-keyboard-event": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"presentation-device-manage": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"requestsync-manager": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"secureelement-manage": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"inputport": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"external-app": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"system-update": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"presentation": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"open-hidden-window": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
|
@ -728,7 +641,7 @@ this.isExplicitInPermissionsTable = function(aPermName, aIntStatus, aAppKind) {
|
|||
appStatus = "privileged";
|
||||
break;
|
||||
default: // If it isn't certified or privileged, it's app
|
||||
appStatus = aAppKind == "hosted-trusted" ? "trusted" : "app";
|
||||
appStatus = "app";
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,8 +16,6 @@ const APP_TRUSTED_ROOTS= ["AppMarketplaceProdPublicRoot",
|
|||
"AppMarketplaceDevPublicRoot",
|
||||
"AppMarketplaceDevReviewersRoot",
|
||||
"AppMarketplaceStageRoot",
|
||||
"TrustedHostedAppPublicRoot",
|
||||
"TrustedHostedAppTestRoot",
|
||||
"AppXPCShellRoot"];
|
||||
|
||||
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",
|
||||
"resource://gre/modules/Langpacks.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "TrustedHostedAppsUtils",
|
||||
"resource://gre/modules/TrustedHostedAppsUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ImportExport",
|
||||
"resource://gre/modules/ImportExport.jsm");
|
||||
|
||||
|
@ -191,7 +188,6 @@ this.DOMApplicationRegistry = {
|
|||
get kPackaged() "packaged",
|
||||
get kHosted() "hosted",
|
||||
get kHostedAppcache() "hosted-appcache",
|
||||
get kTrustedHosted() "hosted-trusted",
|
||||
|
||||
// Path to the webapps.json file where we store the registry data.
|
||||
appsFile: null,
|
||||
|
@ -466,9 +462,7 @@ this.DOMApplicationRegistry = {
|
|||
} else {
|
||||
// Hosted apps, can be appcached or not.
|
||||
let kind = this.kHosted;
|
||||
if (aManifest.type == "trusted") {
|
||||
kind = this.kTrustedHosted;
|
||||
} else if (aManifest.appcache_path) {
|
||||
if (aManifest.appcache_path) {
|
||||
kind = this.kHostedAppcache;
|
||||
}
|
||||
return kind;
|
||||
|
@ -1590,24 +1584,6 @@ this.DOMApplicationRegistry = {
|
|||
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
|
||||
// stringified as an empty object. (see bug 830376)
|
||||
let appClone = AppsUtils.cloneAppObject(app);
|
||||
|
@ -1929,9 +1905,7 @@ this.DOMApplicationRegistry = {
|
|||
|
||||
startOfflineCacheDownload: function(aManifest, aApp, aProfileDir, aIsUpdate) {
|
||||
debug("startOfflineCacheDownload " + aApp.id + " " + aApp.kind);
|
||||
if ((aApp.kind !== this.kHostedAppcache &&
|
||||
aApp.kind !== this.kTrustedHosted) ||
|
||||
!aManifest.appcache_path) {
|
||||
if (aApp.kind !== this.kHostedAppcache || !aManifest.appcache_path) {
|
||||
return;
|
||||
}
|
||||
debug("startOfflineCacheDownload " + aManifest.appcache_path);
|
||||
|
@ -2072,8 +2046,7 @@ this.DOMApplicationRegistry = {
|
|||
|
||||
if (onlyCheckAppCache) {
|
||||
// Bail out for packaged apps & hosted apps without appcache.
|
||||
if (aApp.kind !== this.kHostedAppcache &&
|
||||
aApp.kind !== this.kTrustedHosted) {
|
||||
if (aApp.kind !== this.kHostedAppcache) {
|
||||
sendError("NOT_UPDATABLE");
|
||||
return;
|
||||
}
|
||||
|
@ -2187,16 +2160,7 @@ this.DOMApplicationRegistry = {
|
|||
|
||||
// For hosted apps and hosted apps with appcache, use the
|
||||
// manifest "as is".
|
||||
if (this.kTrustedHosted !== this.appKind(app, 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);
|
||||
this.updateHostedApp(aData, id, app, oldManifest, manifest);
|
||||
}
|
||||
}
|
||||
} else if (xhr.status == 304) {
|
||||
|
@ -2375,9 +2339,7 @@ this.DOMApplicationRegistry = {
|
|||
this.webapps[aId] = aApp;
|
||||
yield this._saveApps();
|
||||
|
||||
if ((aApp.kind !== this.kHostedAppcache &&
|
||||
aApp.kind !== this.kTrustedHosted) ||
|
||||
!aApp.manifest.appcache_path) {
|
||||
if (aApp.kind !== this.kHostedAppcache || !aApp.manifest.appcache_path) {
|
||||
MessageBroadcaster.broadcastMessage("Webapps:UpdateState", {
|
||||
app: aApp,
|
||||
manifest: aApp.manifest,
|
||||
|
@ -2533,12 +2495,7 @@ this.DOMApplicationRegistry = {
|
|||
if (app.manifest) {
|
||||
if (checkManifest()) {
|
||||
debug("Installed manifest check OK");
|
||||
if (this.kTrustedHosted !== this.appKind(app, app.manifest)) {
|
||||
installApp();
|
||||
return;
|
||||
}
|
||||
TrustedHostedAppsUtils.verifyManifest(aData.app, aData.appId, app.manifest)
|
||||
.then(installApp, sendError);
|
||||
installApp();
|
||||
} else {
|
||||
debug("Installed manifest check failed");
|
||||
// checkManifest() sends error before return
|
||||
|
@ -2566,14 +2523,7 @@ this.DOMApplicationRegistry = {
|
|||
if (checkManifest()) {
|
||||
debug("Downloaded manifest check OK");
|
||||
app.etag = xhr.getResponseHeader("Etag");
|
||||
if (this.kTrustedHosted !== this.appKind(app, app.manifest)) {
|
||||
installApp();
|
||||
return;
|
||||
}
|
||||
|
||||
debug("App kind: " + this.kTrustedHosted);
|
||||
TrustedHostedAppsUtils.verifyManifest(aData.app, aData.appId, app.manifest)
|
||||
.then(installApp, sendError);
|
||||
installApp();
|
||||
return;
|
||||
} else {
|
||||
debug("Downloaded manifest check failed");
|
||||
|
@ -2832,9 +2782,6 @@ this.DOMApplicationRegistry = {
|
|||
aNewApp.appStatus || Ci.nsIPrincipal.APP_STATUS_INSTALLED;
|
||||
|
||||
let usesAppcache = appObject.kind == this.kHostedAppcache;
|
||||
if (appObject.kind == this.kTrustedHosted && aManifest.appcache_path) {
|
||||
usesAppcache = true;
|
||||
}
|
||||
|
||||
if (usesAppcache) {
|
||||
appObject.installState = "pending";
|
||||
|
@ -2848,8 +2795,7 @@ this.DOMApplicationRegistry = {
|
|||
appObject.downloading = true;
|
||||
appObject.downloadSize = aLocaleManifest.size;
|
||||
appObject.readyToApplyDownload = false;
|
||||
} else if (appObject.kind == this.kHosted ||
|
||||
appObject.kind == this.kTrustedHosted) {
|
||||
} else if (appObject.kind == this.kHosted) {
|
||||
appObject.installState = "installed";
|
||||
appObject.downloadAvailable = false;
|
||||
appObject.downloading = false;
|
||||
|
@ -3030,9 +2976,7 @@ this.DOMApplicationRegistry = {
|
|||
|
||||
let dontNeedNetwork = false;
|
||||
|
||||
if ((appObject.kind == this.kHostedAppcache ||
|
||||
appObject.kind == this.kTrustedHosted) &&
|
||||
manifest.appcache_path) {
|
||||
if (appObject.kind == this.kHostedAppcache && manifest.appcache_path) {
|
||||
this.queuedDownload[app.manifestURL] = {
|
||||
manifest: manifest,
|
||||
app: appObject,
|
||||
|
|
|
@ -48,7 +48,6 @@ EXTRA_PP_JS_MODULES += [
|
|||
'InterAppCommService.jsm',
|
||||
'OperatorApps.jsm',
|
||||
'ScriptPreloader.jsm',
|
||||
'TrustedHostedAppsUtils.jsm',
|
||||
'Webapps.jsm',
|
||||
]
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ support-files =
|
|||
[test_apps_service.xul]
|
||||
[test_bug_945152.html]
|
||||
skip-if = os != 'linux'
|
||||
[test_tha_utils.html]
|
||||
[test_manifest_helper.xul]
|
||||
[test_operator_app_install.js]
|
||||
[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
|
||||
// shouldn't be necessary. Comment it out and watch the tests fail.
|
||||
if (templatePath == gAppTemplatePath &&
|
||||
(apptype == 'cached' || apptype == 'trusted')) {
|
||||
if (templatePath == gAppTemplatePath && apptype == 'cached') {
|
||||
res = res.replace('<html>', '<html manifest="file_app.sjs?apptype=' + apptype + '&getappcache=true">');
|
||||
}
|
||||
return res;
|
||||
|
@ -49,7 +48,7 @@ function handleRequest(request, response) {
|
|||
|
||||
// Get the app type.
|
||||
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;
|
||||
|
||||
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
|
||||
// state is shared.
|
||||
if ((apptype == 'cached' || apptype == 'trusted') &&
|
||||
if ((apptype == 'cached') &&
|
||||
'getappcache' in query) {
|
||||
response.setHeader("Content-Type", "text/cache-manifest", false);
|
||||
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_manifest.json
|
||||
file_manifest.json^headers^
|
||||
file_trusted_app.template.webapp
|
||||
file_invalidWidget_app.template.webapp
|
||||
file_packaged_app.sjs
|
||||
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 gHostedManifestURL = gBaseURL + 'file_app.sjs?apptype=hosted&getmanifest=true';
|
||||
var gCachedManifestURL = gBaseURL + 'file_app.sjs?apptype=cached&getmanifest=true';
|
||||
var gTrustedManifestURL = gBaseURL + 'file_app.sjs?apptype=trusted&getmanifest=true';
|
||||
var gGenerator;
|
||||
// We need to set the trusted hosted app csp pref since it's only in
|
||||
// b2g.js for now.
|
||||
function setCSPPrefs() {
|
||||
SpecialPowers.pushPrefEnv({'set':[["security.apps.trusted.CSP.default",
|
||||
"default-src *; object-src 'none'"], ["dom.mozBrowserFramesEnabled",true]]},
|
||||
SpecialPowers.pushPrefEnv({'set':[["dom.mozBrowserFramesEnabled",true]]},
|
||||
function() { gGenerator = runTest(); gGenerator.next(); });
|
||||
}
|
||||
|
||||
|
@ -190,54 +188,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=826058
|
|||
request.onsuccess = continueTest;
|
||||
yield undefined;
|
||||
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) {
|
||||
|
|
|
@ -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,
|
||||
aOrigin,
|
||||
aManifest) {
|
||||
// Test if the launch path of the app has the right permission.
|
||||
let newManifest = new ManifestHelper(aManifest, aOrigin, aManifestURL);
|
||||
let launchUrl = newManifest.fullLaunchPath();
|
||||
return this.isSystemMessagePermittedToSend(aSysMsgName,
|
||||
launchUrl,
|
||||
aManifestURL);
|
||||
// Test if the launch path of the app has the right permission.
|
||||
let newManifest = new ManifestHelper(aManifest, aOrigin, aManifestURL);
|
||||
let launchUrl = newManifest.fullLaunchPath();
|
||||
return this.isSystemMessagePermittedToSend(aSysMsgName,
|
||||
launchUrl,
|
||||
aManifestURL);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -84,16 +84,6 @@ AppTrustDomain::SetTrustedRoot(AppTrustedRoot trustedRoot)
|
|||
trustedDER.len = mozilla::ArrayLength(xpcshellRoot);
|
||||
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:
|
||||
trustedDER.data = const_cast<uint8_t*>(addonsPublicRoot);
|
||||
trustedDER.len = mozilla::ArrayLength(addonsPublicRoot);
|
||||
|
|
|
@ -46,7 +46,7 @@ interface nsIVerifySignedManifestCallback : nsISupports
|
|||
* This represents a service to access and manipulate
|
||||
* X.509 certificates stored in a database.
|
||||
*/
|
||||
[scriptable, uuid(fbe2a0c8-ec51-4ea4-80b3-e16793141967)]
|
||||
[scriptable, uuid(c9fdec46-5c4c-4b1d-a0ca-c2bc10151b69)]
|
||||
interface nsIX509CertDB : nsISupports {
|
||||
|
||||
/**
|
||||
|
@ -316,10 +316,8 @@ interface nsIX509CertDB : nsISupports {
|
|||
const AppTrustedRoot AppMarketplaceDevReviewersRoot = 4;
|
||||
const AppTrustedRoot AppMarketplaceStageRoot = 5;
|
||||
const AppTrustedRoot AppXPCShellRoot = 6;
|
||||
const AppTrustedRoot TrustedHostedAppPublicRoot = 7;
|
||||
const AppTrustedRoot TrustedHostedAppTestRoot = 8;
|
||||
const AppTrustedRoot AddonsPublicRoot = 9;
|
||||
const AppTrustedRoot AddonsStageRoot = 10;
|
||||
const AppTrustedRoot AddonsPublicRoot = 7;
|
||||
const AppTrustedRoot AddonsStageRoot = 8;
|
||||
void openSignedAppFileAsync(in AppTrustedRoot trustedRoot,
|
||||
in nsIFile aJarFile,
|
||||
in nsIOpenSignedAppFileCallback callback);
|
||||
|
|
Загрузка…
Ссылка в новой задаче