Backed out 24 changesets (bug 1173523, bug 1172080, bug 817007, bug 1165263) for android reftest bustage CLOSED TREE

Backed out changeset 84fe04b2e7d1 (bug 1172080)
Backed out changeset 0ff004760a1f (bug 1172080)
Backed out changeset af147585ad55 (bug 1165263)
Backed out changeset c3af8ebb6db0 (bug 1165263)
Backed out changeset cd3f33a888fe (bug 1165263)
Backed out changeset e5db39044a1e (bug 1165263)
Backed out changeset c01c9ed77061 (bug 1165263)
Backed out changeset fb723aaa4267 (bug 1165263)
Backed out changeset f754e52e74dc (bug 1165263)
Backed out changeset c6bda3a0afd6 (bug 817007)
Backed out changeset bfa100253349 (bug 817007)
Backed out changeset b787b3f9aadc (bug 1173523)
Backed out changeset 4a0676b73f77 (bug 1173523)
Backed out changeset 82034a4560c5 (bug 1173523)
Backed out changeset 4bdb91114c7a (bug 1173523)
Backed out changeset 72406261eccc (bug 1173523)
Backed out changeset 541b6faf7196 (bug 1173523)
Backed out changeset 1caac4569616 (bug 1173523)
Backed out changeset 0d4f9f9e1b4e (bug 1173523)
Backed out changeset 2d5661eb966c (bug 1173523)
Backed out changeset 89833c0bb0cd (bug 1173523)
Backed out changeset ea64d70eacfe (bug 1173523)
Backed out changeset a8e4f1c0c445 (bug 1173523)
Backed out changeset cf498d466b85 (bug 1173523)
This commit is contained in:
Wes Kocher 2015-07-14 14:00:32 -07:00
parent 1d6f011995
commit 24d022d24f
60 changed files with 821 additions and 1686 deletions

View File

@ -1,21 +1,21 @@
# This file has default permissions for the permission manager. # This file has default permissions for the permission manager.
# The file-format is strict: # The file-format is strict:
# * matchtype \t type \t permission \t host # * matchtype \t type \t permission \t host
# * "origin" should be used for matchtype, "host" is supported for legacy reasons # * Only "host" is supported for matchtype
# * type is a string that identifies the type of permission (e.g. "cookie") # * type is a string that identifies the type of permission (e.g. "cookie")
# * permission is an integer between 1 and 15 # * permission is an integer between 1 and 15
# See nsPermissionManager.cpp for more... # See nsPermissionManager.cpp for more...
# UITour # UITour
origin uitour 1 https://www.mozilla.org host uitour 1 www.mozilla.org
origin uitour 1 https://self-repair.mozilla.org host uitour 1 self-repair.mozilla.org
origin uitour 1 https://support.mozilla.org host uitour 1 support.mozilla.org
origin uitour 1 about:home host uitour 1 about:home
# XPInstall # XPInstall
origin install 1 https://addons.mozilla.org host install 1 addons.mozilla.org
origin install 1 https://marketplace.firefox.com host install 1 marketplace.firefox.com
# Remote troubleshooting # Remote troubleshooting
origin remote-troubleshooting 1 https://input.mozilla.org host remote-troubleshooting 1 input.mozilla.org
origin remote-troubleshooting 1 https://support.mozilla.org host remote-troubleshooting 1 support.mozilla.org

View File

@ -44,14 +44,14 @@ var gPluginHandler = {
switch (msg.name) { switch (msg.name) {
case "PluginContent:ShowClickToPlayNotification": case "PluginContent:ShowClickToPlayNotification":
this.showClickToPlayNotification(msg.target, msg.data.plugins, msg.data.showNow, this.showClickToPlayNotification(msg.target, msg.data.plugins, msg.data.showNow,
msg.principal, msg.data.location); msg.principal, msg.data.host, msg.data.location);
break; break;
case "PluginContent:RemoveNotification": case "PluginContent:RemoveNotification":
this.removeNotification(msg.target, msg.data.name); this.removeNotification(msg.target, msg.data.name);
break; break;
case "PluginContent:UpdateHiddenPluginUI": case "PluginContent:UpdateHiddenPluginUI":
this.updateHiddenPluginUI(msg.target, msg.data.haveInsecure, msg.data.actions, this.updateHiddenPluginUI(msg.target, msg.data.haveInsecure, msg.data.actions,
msg.principal, msg.data.location); msg.principal, msg.data.host, msg.data.location);
break; break;
case "PluginContent:HideNotificationBar": case "PluginContent:HideNotificationBar":
this.hideNotificationBar(msg.target, msg.data.name); this.hideNotificationBar(msg.target, msg.data.name);
@ -216,8 +216,8 @@ var gPluginHandler = {
}); });
}, },
showClickToPlayNotification: function (browser, plugins, showNow, showClickToPlayNotification: function (browser, plugins, showNow, principal,
principal, location) { host, location) {
// It is possible that we've received a message from the frame script to show // It is possible that we've received a message from the frame script to show
// a click to play notification for a principal that no longer matches the one // a click to play notification for a principal that no longer matches the one
// that the browser's content now has assigned (ie, the browser has browsed away // that the browser's content now has assigned (ie, the browser has browsed away
@ -295,6 +295,7 @@ var gPluginHandler = {
primaryPlugin: primaryPluginPermission, primaryPlugin: primaryPluginPermission,
pluginData: pluginData, pluginData: pluginData,
principal: principal, principal: principal,
host: host,
}; };
PopupNotifications.show(browser, "click-to-play-plugins", PopupNotifications.show(browser, "click-to-play-plugins",
"", "plugins-notification-icon", "", "plugins-notification-icon",
@ -315,10 +316,8 @@ var gPluginHandler = {
notificationBox.removeNotification(notification, true); notificationBox.removeNotification(notification, true);
}, },
updateHiddenPluginUI: function (browser, haveInsecure, actions, updateHiddenPluginUI: function (browser, haveInsecure, actions, principal,
principal, location) { host, location) {
let origin = principal.originNoSuffix;
// It is possible that we've received a message from the frame script to show // It is possible that we've received a message from the frame script to show
// the hidden plugin notification for a principal that no longer matches the one // the hidden plugin notification for a principal that no longer matches the one
// that the browser's content now has assigned (ie, the browser has browsed away // that the browser's content now has assigned (ie, the browser has browsed away
@ -381,22 +380,22 @@ var gPluginHandler = {
case Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY: case Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY:
message = gNavigatorBundle.getFormattedString( message = gNavigatorBundle.getFormattedString(
"pluginActivateNew.message", "pluginActivateNew.message",
[pluginName, origin]); [pluginName, host]);
break; break;
case Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE: case Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE:
message = gNavigatorBundle.getFormattedString( message = gNavigatorBundle.getFormattedString(
"pluginActivateOutdated.message", "pluginActivateOutdated.message",
[pluginName, origin, brand]); [pluginName, host, brand]);
break; break;
case Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE: case Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE:
message = gNavigatorBundle.getFormattedString( message = gNavigatorBundle.getFormattedString(
"pluginActivateVulnerable.message", "pluginActivateVulnerable.message",
[pluginName, origin, brand]); [pluginName, host, brand]);
} }
} else { } else {
// Multi-plugin // Multi-plugin
message = gNavigatorBundle.getFormattedString( message = gNavigatorBundle.getFormattedString(
"pluginActivateMultiple.message", [origin]); "pluginActivateMultiple.message", [host]);
} }
let buttons = [ let buttons = [

View File

@ -99,11 +99,7 @@ let TrackingProtection = {
// Remove the current host from the 'trackingprotection' consumer // Remove the current host from the 'trackingprotection' consumer
// of the permission manager. This effectively removes this host // of the permission manager. This effectively removes this host
// from the tracking protection allowlist. // from the tracking protection allowlist.
let normalizedUrl = Services.io.newURI( Services.perms.remove(gBrowser.selectedBrowser.currentURI,
"https://" + gBrowser.selectedBrowser.currentURI.hostPort,
null, null);
Services.perms.remove(normalizedUrl,
"trackingprotection"); "trackingprotection");
// Telemetry for enable protection. // Telemetry for enable protection.

View File

@ -1117,9 +1117,8 @@ var imagePermissionObserver = {
var row = getSelectedRow(imageTree); var row = getSelectedRow(imageTree);
var item = gImageView.data[row][COL_IMAGE_NODE]; var item = gImageView.data[row][COL_IMAGE_NODE];
var url = gImageView.data[row][COL_IMAGE_ADDRESS]; var url = gImageView.data[row][COL_IMAGE_ADDRESS];
if (permission.matchesURI(makeURI(url), true)) { if (makeURI(url).host == permission.host)
makeBlockImage(url); makeBlockImage(url);
}
} }
} }
} }

View File

@ -18,7 +18,7 @@ var permissionObserver = {
{ {
if (aTopic == "perm-changed") { if (aTopic == "perm-changed") {
var permission = aSubject.QueryInterface(Components.interfaces.nsIPermission); var permission = aSubject.QueryInterface(Components.interfaces.nsIPermission);
if (permission.matchesURI(gPermURI, true)) { if (permission.host == gPermURI.host) {
if (gPermissions.indexOf(permission.type) > -1) if (gPermissions.indexOf(permission.type) > -1)
initRow(permission.type); initRow(permission.type);
else if (permission.type.startsWith("plugin")) else if (permission.type.startsWith("plugin"))
@ -35,7 +35,7 @@ function onLoadPermission()
if (SitePermissions.isSupportedURI(uri)) { if (SitePermissions.isSupportedURI(uri)) {
gPermURI = uri; gPermURI = uri;
var hostText = document.getElementById("hostText"); var hostText = document.getElementById("hostText");
hostText.value = gPermURI.prePath; hostText.value = gPermURI.host;
for (var i of gPermissions) for (var i of gPermissions)
initRow(i); initRow(i);

View File

@ -48,7 +48,7 @@ function test_install_lwtheme() {
is(LightweightThemeManager.currentTheme, null, "Should be no lightweight theme selected"); is(LightweightThemeManager.currentTheme, null, "Should be no lightweight theme selected");
var pm = Services.perms; var pm = Services.perms;
pm.add(makeURI("https://example.com/"), "install", pm.ALLOW_ACTION); pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
gBrowser.selectedTab = gBrowser.addTab("https://example.com/browser/browser/base/content/test/general/bug592338.html"); gBrowser.selectedTab = gBrowser.addTab("https://example.com/browser/browser/base/content/test/general/bug592338.html");
gBrowser.selectedBrowser.addEventListener("pageshow", function() { gBrowser.selectedBrowser.addEventListener("pageshow", function() {

View File

@ -238,7 +238,7 @@ function clearAllPluginPermissions() {
while (perms.hasMoreElements()) { while (perms.hasMoreElements()) {
let perm = perms.getNext(); let perm = perms.getNext();
if (perm.type.startsWith('plugin')) { if (perm.type.startsWith('plugin')) {
info("removing permission:" + perm.principal.origin + " " + perm.type + "\n"); info("removing permission:" + perm.host + " " + perm.type + "\n");
Services.perms.removePermission(perm); Services.perms.removePermission(perm);
} }
} }

View File

@ -2432,9 +2432,9 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
let normalizedUrl = Services.io.newURI( let normalizedUrl = Services.io.newURI(
"https://" + gBrowser.selectedBrowser.currentURI.hostPort, "https://" + gBrowser.selectedBrowser.currentURI.hostPort,
null, null); null, null);
// Add the current host/port combination in the 'trackingprotection' consumer of // Add the current host in the 'trackingprotection' consumer of
// the permission manager using a normalized URI. This effectively // the permission manager using a normalized URI. This effectively
// places this host/port combination on the tracking protection allowlist. // places this host on the tracking protection allowlist.
Services.perms.add(normalizedUrl, Services.perms.add(normalizedUrl,
"trackingprotection", Services.perms.ALLOW_ACTION); "trackingprotection", Services.perms.ALLOW_ACTION);
BrowserReload(); BrowserReload();
@ -2442,13 +2442,10 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
</method> </method>
<method name="enableTrackingContentProtection"> <method name="enableTrackingContentProtection">
<body><![CDATA[ <body><![CDATA[
// Remove the current host/port combination from the 'trackingprotection' consumer // Remove the current host from the 'trackingprotection' consumer
// of the permission manager. This effectively removes this host/port combination // of the permission manager. This effectively removes this host
// from the tracking protection allowlist. // from the tracking protection allowlist.
let normalizedUrl = Services.io.newURI( Services.perms.remove(gBrowser.selectedBrowser.currentURI,
"https://" + gBrowser.selectedBrowser.currentURI.hostPort,
null, null);
Services.perms.remove(normalizedUrl,
"trackingprotection"); "trackingprotection");
BrowserReload(); BrowserReload();
]]></body> ]]></body>
@ -2564,8 +2561,8 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
return; return;
} }
let prePath = this.notification.options.principal.URI.prePath; let host = this.notification.options.host;
this._setupDescription("pluginActivateMultiple.message", null, prePath); this._setupDescription("pluginActivateMultiple.message", null, host);
var showBox = document.getAnonymousElementByAttribute(this, "anonid", "plugin-notification-showbox"); var showBox = document.getAnonymousElementByAttribute(this, "anonid", "plugin-notification-showbox");
@ -2604,7 +2601,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
<method name="_setupSingleState"> <method name="_setupSingleState">
<body><![CDATA[ <body><![CDATA[
var action = this._items[0].action; var action = this._items[0].action;
var prePath = action.pluginPermissionPrePath; var host = action.pluginPermissionHost;
let label, linkLabel, linkUrl, button1, button2; let label, linkLabel, linkUrl, button1, button2;
@ -2699,7 +2696,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
Cu.reportError(Error("Unexpected blocklist state")); Cu.reportError(Error("Unexpected blocklist state"));
} }
} }
this._setupDescription(label, action.pluginName, prePath); this._setupDescription(label, action.pluginName, host);
this._setupLink(linkLabel, action.detailsLink); this._setupLink(linkLabel, action.detailsLink);
this._primaryButton.label = gNavigatorBundle.getString(button1.label); this._primaryButton.label = gNavigatorBundle.getString(button1.label);
@ -2720,7 +2717,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
<method name="_setupDescription"> <method name="_setupDescription">
<parameter name="baseString" /> <parameter name="baseString" />
<parameter name="pluginName" /> <!-- null for the multiple-plugin case --> <parameter name="pluginName" /> <!-- null for the multiple-plugin case -->
<parameter name="prePath" /> <parameter name="host" />
<body><![CDATA[ <body><![CDATA[
var bsn = this._brandShortName; var bsn = this._brandShortName;
var span = document.getAnonymousElementByAttribute(this, "anonid", "click-to-play-plugins-notification-description"); var span = document.getAnonymousElementByAttribute(this, "anonid", "click-to-play-plugins-notification-description");
@ -2728,17 +2725,17 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
span.removeChild(span.lastChild); span.removeChild(span.lastChild);
} }
var args = ["__prepath__", this._brandShortName]; var args = ["__host__", this._brandShortName];
if (pluginName) { if (pluginName) {
args.unshift(pluginName); args.unshift(pluginName);
} }
var bases = gNavigatorBundle.getFormattedString(baseString, args). var bases = gNavigatorBundle.getFormattedString(baseString, args).
split("__prepath__", 2); split("__host__", 2);
span.appendChild(document.createTextNode(bases[0])); span.appendChild(document.createTextNode(bases[0]));
var prePathSpan = document.createElementNS("http://www.w3.org/1999/xhtml", "em"); var hostSpan = document.createElementNS("http://www.w3.org/1999/xhtml", "em");
prePathSpan.appendChild(document.createTextNode(prePath)); hostSpan.appendChild(document.createTextNode(host));
span.appendChild(prePathSpan); span.appendChild(hostSpan);
span.appendChild(document.createTextNode(bases[1] + " ")); span.appendChild(document.createTextNode(bases[1] + " "));
]]></body> ]]></body>
</method> </method>

View File

@ -17,9 +17,6 @@ Cu.import("resource://gre/modules/ForgetAboutSite.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm", XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
"resource://gre/modules/PluralForm.jsm"); "resource://gre/modules/PluralForm.jsm");
let gSecMan = Cc["@mozilla.org/scriptsecuritymanager;1"].
getService(Ci.nsIScriptSecurityManager);
let gFaviconService = Cc["@mozilla.org/browser/favicon-service;1"]. let gFaviconService = Cc["@mozilla.org/browser/favicon-service;1"].
getService(Ci.nsIFaviconService); getService(Ci.nsIFaviconService);
@ -29,7 +26,7 @@ let gPlacesDatabase = Cc["@mozilla.org/browser/nav-history-service;1"].
clone(true); clone(true);
let gSitesStmt = gPlacesDatabase.createAsyncStatement( let gSitesStmt = gPlacesDatabase.createAsyncStatement(
"SELECT url " + "SELECT get_unreversed_host(rev_host) AS host " +
"FROM moz_places " + "FROM moz_places " +
"WHERE rev_host > '.' " + "WHERE rev_host > '.' " +
"AND visit_count > 0 " + "AND visit_count > 0 " +
@ -49,11 +46,14 @@ let gVisitStmt = gPlacesDatabase.createAsyncStatement(
let TEST_EXACT_PERM_TYPES = ["geo", "camera", "microphone"]; let TEST_EXACT_PERM_TYPES = ["geo", "camera", "microphone"];
/** /**
* Site object represents a single site, uniquely identified by a principal. * Site object represents a single site, uniquely identified by a host.
*/ */
function Site(principal) { function Site(host) {
this.principal = principal; this.host = host;
this.listitem = null; this.listitem = null;
this.httpURI = NetUtil.newURI("http://" + this.host);
this.httpsURI = NetUtil.newURI("https://" + this.host);
} }
Site.prototype = { Site.prototype = {
@ -75,10 +75,16 @@ Site.prototype = {
} }
} }
// Get the favicon for the origin // Try to find favicon for both URIs, but always prefer the https favicon.
gFaviconService.getFaviconURLForPage(this.principal.URI, function (aURI) { gFaviconService.getFaviconURLForPage(this.httpsURI, function (aURI) {
if (aURI) { if (aURI) {
invokeCallback(aURI); invokeCallback(aURI);
} else {
gFaviconService.getFaviconURLForPage(this.httpURI, function (aURI) {
if (aURI) {
invokeCallback(aURI);
}
});
} }
}.bind(this)); }.bind(this));
}, },
@ -90,9 +96,7 @@ Site.prototype = {
* A function that takes the visit count (a number) as a parameter. * A function that takes the visit count (a number) as a parameter.
*/ */
getVisitCount: function Site_getVisitCount(aCallback) { getVisitCount: function Site_getVisitCount(aCallback) {
// XXX This won't be a very reliable system, as it will count both http: and https: visits let rev_host = this.host.split("").reverse().join("") + ".";
// Unfortunately, I don't think that there is a much better way to do it right now.
let rev_host = this.principal.URI.host.split("").reverse().join("") + ".";
gVisitStmt.params.rev_host = rev_host; gVisitStmt.params.rev_host = rev_host;
gVisitStmt.executeAsync({ gVisitStmt.executeAsync({
handleResult: function(aResults) { handleResult: function(aResults) {
@ -135,9 +139,9 @@ Site.prototype = {
let permissionValue; let permissionValue;
if (TEST_EXACT_PERM_TYPES.indexOf(aType) == -1) { if (TEST_EXACT_PERM_TYPES.indexOf(aType) == -1) {
permissionValue = Services.perms.testPermissionFromPrincipal(this.principal, aType); permissionValue = Services.perms.testPermission(this.httpURI, aType);
} else { } else {
permissionValue = Services.perms.testExactPermissionFromPrincipal(this.principal, aType); permissionValue = Services.perms.testExactPermission(this.httpURI, aType);
} }
aResultObj.value = permissionValue; aResultObj.value = permissionValue;
@ -162,7 +166,9 @@ Site.prototype = {
return; return;
} }
Services.perms.addFromPrincipal(this.principal, aType, aPerm); // Using httpURI is kind of bogus, but the permission manager stores the
// permission for the host, so the right thing happens in the end.
Services.perms.add(this.httpURI, aType, aPerm);
}, },
/** /**
@ -173,7 +179,7 @@ Site.prototype = {
* e.g. "cookie", "geo", "indexedDB", "popup", "image" * e.g. "cookie", "geo", "indexedDB", "popup", "image"
*/ */
clearPermission: function Site_clearPermission(aType) { clearPermission: function Site_clearPermission(aType) {
Services.perms.removeFromPrincipal(this.principal, aType); Services.perms.remove(this.httpURI, aType);
}, },
/** /**
@ -183,14 +189,13 @@ Site.prototype = {
* @return An array of the cookies set for the site. * @return An array of the cookies set for the site.
*/ */
get cookies() { get cookies() {
let host = this.principal.URI.host;
let cookies = []; let cookies = [];
let enumerator = Services.cookies.getCookiesFromHost(host); let enumerator = Services.cookies.getCookiesFromHost(this.host);
while (enumerator.hasMoreElements()) { while (enumerator.hasMoreElements()) {
let cookie = enumerator.getNext().QueryInterface(Ci.nsICookie2); let cookie = enumerator.getNext().QueryInterface(Ci.nsICookie2);
// getCookiesFromHost returns cookies for base domain, but we only want // getCookiesFromHost returns cookies for base domain, but we only want
// the cookies for the exact domain. // the cookies for the exact domain.
if (cookie.rawHost == host) { if (cookie.rawHost == this.host) {
cookies.push(cookie); cookies.push(cookie);
} }
} }
@ -212,27 +217,27 @@ Site.prototype = {
* @return An array of the logins stored for the site. * @return An array of the logins stored for the site.
*/ */
get logins() { get logins() {
let logins = Services.logins.findLogins({}, this.principal.originNoSuffix, "", ""); let httpLogins = Services.logins.findLogins({}, this.httpURI.prePath, "", "");
return logins; let httpsLogins = Services.logins.findLogins({}, this.httpsURI.prePath, "", "");
return httpLogins.concat(httpsLogins);
}, },
get loginSavingEnabled() { get loginSavingEnabled() {
return Services.logins.getLoginSavingEnabled(this.principal.originNoSuffix); // Only say that login saving is blocked if it is blocked for both http and https.
return Services.logins.getLoginSavingEnabled(this.httpURI.prePath) &&
Services.logins.getLoginSavingEnabled(this.httpsURI.prePath);
}, },
set loginSavingEnabled(isEnabled) { set loginSavingEnabled(isEnabled) {
Services.logins.setLoginSavingEnabled(this.principal.originNoSuffix, isEnabled); Services.logins.setLoginSavingEnabled(this.httpURI.prePath, isEnabled);
Services.logins.setLoginSavingEnabled(this.httpsURI.prePath, isEnabled);
}, },
/** /**
* Removes all data from the browser corresponding to the site. * Removes all data from the browser corresponding to the site.
*/ */
forgetSite: function Site_forgetSite() { forgetSite: function Site_forgetSite() {
// XXX This removes data for an entire domain, rather than just ForgetAboutSite.removeDataFromDomain(this.host);
// an origin. This may produce confusing results, as data will
// be cleared for the http:// as well as the https:// domain
// if you try to forget the https:// site.
ForgetAboutSite.removeDataFromDomain(this.principal.URI.host);
} }
} }
@ -361,7 +366,7 @@ let AboutPermissions = {
LIST_BUILD_DELAY: 100, // delay between intervals LIST_BUILD_DELAY: 100, // delay between intervals
/** /**
* Stores a mapping of origin strings to Site objects. * Stores a mapping of host strings to Site objects.
*/ */
_sites: {}, _sites: {},
@ -467,9 +472,9 @@ let AboutPermissions = {
break; break;
} }
let permission = aSubject.QueryInterface(Ci.nsIPermission); let permission = aSubject.QueryInterface(Ci.nsIPermission);
// We can't compare selectedSite.principal and permission.principal here // We can't compare selectedSite.host and permission.host here because
// because we need to handle the case where a parent domain was changed // we need to handle the case where a parent domain was changed in a
// in a way that affects the subdomain. // way that affects the subdomain.
if (this._supportedPermissions.indexOf(permission.type) != -1) { if (this._supportedPermissions.indexOf(permission.type) != -1) {
this.updatePermission(permission.type); this.updatePermission(permission.type);
} }
@ -507,11 +512,8 @@ let AboutPermissions = {
AboutPermissions.startSitesListBatch(); AboutPermissions.startSitesListBatch();
let row; let row;
while (row = aResults.getNextRow()) { while (row = aResults.getNextRow()) {
let spec = row.getResultByName("url"); let host = row.getResultByName("host");
let uri = NetUtil.newURI(spec); AboutPermissions.addHost(host);
let principal = gSecMan.getNoAppCodebasePrincipal(uri);
AboutPermissions.addPrincipal(principal);
} }
AboutPermissions.endSitesListBatch(); AboutPermissions.endSitesListBatch();
}, },
@ -560,8 +562,7 @@ let AboutPermissions = {
try { try {
// aLogin.hostname is a string in origin URL format (e.g. "http://foo.com") // aLogin.hostname is a string in origin URL format (e.g. "http://foo.com")
let uri = NetUtil.newURI(aLogin.hostname); let uri = NetUtil.newURI(aLogin.hostname);
let principal = gSecMan.getNoAppCodebasePrincipal(uri); this.addHost(uri.host);
this.addPrincipal(principal);
} catch (e) { } catch (e) {
// newURI will throw for add-ons logins stored in chrome:// URIs // newURI will throw for add-ons logins stored in chrome:// URIs
} }
@ -576,8 +577,7 @@ let AboutPermissions = {
try { try {
// aHostname is a string in origin URL format (e.g. "http://foo.com") // aHostname is a string in origin URL format (e.g. "http://foo.com")
let uri = NetUtil.newURI(aHostname); let uri = NetUtil.newURI(aHostname);
let principal = gSecMan.getNoAppCodebasePrincipal(uri); this.addHost(uri.host);
this.addPrincipal(principal);
} catch (e) { } catch (e) {
// newURI will throw for add-ons logins stored in chrome:// URIs // newURI will throw for add-ons logins stored in chrome:// URIs
} }
@ -592,7 +592,7 @@ let AboutPermissions = {
let permission = enumerator.getNext().QueryInterface(Ci.nsIPermission); let permission = enumerator.getNext().QueryInterface(Ci.nsIPermission);
// Only include sites with exceptions set for supported permission types. // Only include sites with exceptions set for supported permission types.
if (this._supportedPermissions.indexOf(permission.type) != -1) { if (this._supportedPermissions.indexOf(permission.type) != -1) {
this.addPrincipal(permission.principal); this.addHost(permission.host);
} }
itemCnt++; itemCnt++;
} }
@ -603,15 +603,15 @@ let AboutPermissions = {
/** /**
* Creates a new Site and adds it to _sites if it's not already there. * Creates a new Site and adds it to _sites if it's not already there.
* *
* @param aPrincipal * @param aHost
* A principal. * A host string.
*/ */
addPrincipal: function(aPrincipal) { addHost: function(aHost) {
if (aPrincipal.origin in this._sites) { if (aHost in this._sites) {
return; return;
} }
let site = new Site(aPrincipal); let site = new Site(aHost);
this._sites[aPrincipal.origin] = site; this._sites[aHost] = site;
this.addToSitesList(site); this.addToSitesList(site);
}, },
@ -624,7 +624,7 @@ let AboutPermissions = {
addToSitesList: function(aSite) { addToSitesList: function(aSite) {
let item = document.createElement("richlistitem"); let item = document.createElement("richlistitem");
item.setAttribute("class", "site"); item.setAttribute("class", "site");
item.setAttribute("value", aSite.principal.origin); item.setAttribute("value", aSite.host);
aSite.getFavicon(function(aURL) { aSite.getFavicon(function(aURL) {
item.setAttribute("favicon", aURL); item.setAttribute("favicon", aURL);
@ -633,7 +633,7 @@ let AboutPermissions = {
// Make sure to only display relevant items when list is filtered // Make sure to only display relevant items when list is filtered
let filterValue = document.getElementById("sites-filter").value.toLowerCase(); let filterValue = document.getElementById("sites-filter").value.toLowerCase();
item.collapsed = aSite.principal.origin.toLowerCase().indexOf(filterValue) == -1; item.collapsed = aSite.host.toLowerCase().indexOf(filterValue) == -1;
(this._listFragment || this.sitesList).appendChild(item); (this._listFragment || this.sitesList).appendChild(item);
}, },
@ -686,16 +686,16 @@ let AboutPermissions = {
* The host string corresponding to the site to delete. * The host string corresponding to the site to delete.
*/ */
deleteFromSitesList: function(aHost) { deleteFromSitesList: function(aHost) {
for (let origin in this._sites) { for (let host in this._sites) {
let site = this._sites[origin]; let site = this._sites[host];
if (site.principal.URI.host.hasRootDomain(aHost)) { if (site.host.hasRootDomain(aHost)) {
if (site == this._selectedSite) { if (site == this._selectedSite) {
// Replace site-specific interface with "All Sites" interface. // Replace site-specific interface with "All Sites" interface.
this.sitesList.selectedItem = document.getElementById("all-sites-item"); this.sitesList.selectedItem = document.getElementById("all-sites-item");
} }
this.sitesList.removeChild(site.listitem); this.sitesList.removeChild(site.listitem);
delete this._sites[site.principal.origin]; delete this._sites[site.host];
} }
} }
}, },
@ -711,9 +711,9 @@ let AboutPermissions = {
return; return;
} }
let origin = event.target.value; let host = event.target.value;
let site = this._selectedSite = this._sites[origin]; let site = this._selectedSite = this._sites[host];
document.getElementById("site-label").value = origin; document.getElementById("site-label").value = host;
document.getElementById("header-deck").selectedPanel = document.getElementById("header-deck").selectedPanel =
document.getElementById("site-header"); document.getElementById("site-header");
@ -768,9 +768,9 @@ let AboutPermissions = {
// If there is no selected site, we are updating the default permissions interface. // If there is no selected site, we are updating the default permissions interface.
permissionValue = PermissionDefaults[aType]; permissionValue = PermissionDefaults[aType];
if (aType == "cookie") if (aType == "cookie")
// cookie-9 corresponds to ALLOW_FIRST_PARTY_ONLY, which is reserved // cookie-9 corresponds to ALLOW_FIRST_PARTY_ONLY, which is reserved
// for site-specific preferences only. // for site-specific preferences only.
document.getElementById("cookie-9").hidden = true; document.getElementById("cookie-9").hidden = true;
} else { } else {
if (aType == "cookie") if (aType == "cookie")
document.getElementById("cookie-9").hidden = false; document.getElementById("cookie-9").hidden = false;
@ -825,18 +825,18 @@ let AboutPermissions = {
* Opens password manager dialog. * Opens password manager dialog.
*/ */
managePasswords: function() { managePasswords: function() {
let selectedOrigin = ""; let selectedHost = "";
if (this._selectedSite) { if (this._selectedSite) {
selectedOrigin = this._selectedSite.principal.URI.prePath; selectedHost = this._selectedSite.host;
} }
let win = Services.wm.getMostRecentWindow("Toolkit:PasswordManager"); let win = Services.wm.getMostRecentWindow("Toolkit:PasswordManager");
if (win) { if (win) {
win.setFilter(selectedOrigin); win.setFilter(selectedHost);
win.focus(); win.focus();
} else { } else {
window.openDialog("chrome://passwordmgr/content/passwordManager.xul", window.openDialog("chrome://passwordmgr/content/passwordManager.xul",
"Toolkit:PasswordManager", "", {filterString : selectedOrigin}); "Toolkit:PasswordManager", "", {filterString : selectedHost});
} }
}, },
@ -877,11 +877,9 @@ let AboutPermissions = {
* Opens cookie manager dialog. * Opens cookie manager dialog.
*/ */
manageCookies: function() { manageCookies: function() {
// Cookies are stored by-host, and thus we filter the cookie window
// using only the host of the selected principal's origin
let selectedHost = ""; let selectedHost = "";
if (this._selectedSite) { if (this._selectedSite) {
selectedHost = this._selectedSite.principal.URI.host; selectedHost = this._selectedSite.host;
} }
let win = Services.wm.getMostRecentWindow("Browser:Cookies"); let win = Services.wm.getMostRecentWindow("Browser:Cookies");

View File

@ -9,7 +9,6 @@ Components.utils.import("resource://gre/modules/ctypes.jsm");
Components.utils.import("resource://gre/modules/Services.jsm"); Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/LoadContextInfo.jsm"); Components.utils.import("resource://gre/modules/LoadContextInfo.jsm");
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://gre/modules/BrowserUtils.jsm");
var gAdvancedPane = { var gAdvancedPane = {
_inited: false, _inited: false,
@ -472,7 +471,7 @@ var gAdvancedPane = {
var usage = 0; var usage = 0;
for (var i = 0; i < groups.length; i++) { for (var i = 0; i < groups.length; i++) {
var uri = ios.newURI(groups[i], null, null); var uri = ios.newURI(groups[i], null, null);
if (perm.matchesURI(uri, true)) { if (uri.asciiHost == perm.host) {
var cache = cacheService.getActiveCache(groups[i]); var cache = cacheService.getActiveCache(groups[i]);
usage += cache.usage; usage += cache.usage;
} }
@ -509,7 +508,7 @@ var gAdvancedPane = {
var row = document.createElement("listitem"); var row = document.createElement("listitem");
row.id = ""; row.id = "";
row.className = "offlineapp"; row.className = "offlineapp";
row.setAttribute("origin", perm.principal.origin); row.setAttribute("host", perm.host);
var converted = DownloadUtils. var converted = DownloadUtils.
convertByteUnits(this._getOfflineAppUsage(perm, groups)); convertByteUnits(this._getOfflineAppUsage(perm, groups));
row.setAttribute("usage", row.setAttribute("usage",
@ -535,8 +534,7 @@ var gAdvancedPane = {
{ {
var list = document.getElementById("offlineAppsList"); var list = document.getElementById("offlineAppsList");
var item = list.selectedItem; var item = list.selectedItem;
var origin = item.getAttribute("origin"); var host = item.getAttribute("host");
var principal = BrowserUtils.principalFromOrigin(origin);
var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"] var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Components.interfaces.nsIPromptService); .getService(Components.interfaces.nsIPromptService);
@ -545,18 +543,13 @@ var gAdvancedPane = {
var bundle = document.getElementById("bundlePreferences"); var bundle = document.getElementById("bundlePreferences");
var title = bundle.getString("offlineAppRemoveTitle"); var title = bundle.getString("offlineAppRemoveTitle");
var prompt = bundle.getFormattedString("offlineAppRemovePrompt", [principal.URI.prePath]); var prompt = bundle.getFormattedString("offlineAppRemovePrompt", [host]);
var confirm = bundle.getString("offlineAppRemoveConfirm"); var confirm = bundle.getString("offlineAppRemoveConfirm");
var result = prompts.confirmEx(window, title, prompt, flags, confirm, var result = prompts.confirmEx(window, title, prompt, flags, confirm,
null, null, null, {}); null, null, null, {});
if (result != 0) if (result != 0)
return; return;
// get the permission
var pm = Components.classes["@mozilla.org/permissionmanager;1"]
.getService(Components.interfaces.nsIPermissionManager);
var perm = pm.getPermissionObject(principal, "offline-app");
// clear offline cache entries // clear offline cache entries
var cacheService = Components.classes["@mozilla.org/network/application-cache-service;1"]. var cacheService = Components.classes["@mozilla.org/network/application-cache-service;1"].
getService(Components.interfaces.nsIApplicationCacheService); getService(Components.interfaces.nsIApplicationCacheService);
@ -564,14 +557,25 @@ var gAdvancedPane = {
getService(Components.interfaces.nsIIOService); getService(Components.interfaces.nsIIOService);
var groups = cacheService.getGroups(); var groups = cacheService.getGroups();
for (var i = 0; i < groups.length; i++) { for (var i = 0; i < groups.length; i++) {
var uri = ios.newURI(groups[i], null, null); let uri = ios.newURI(groups[i], null, null);
if (perm.matchesURI(uri, true)) { if (uri.asciiHost == host) {
var cache = cacheService.getActiveCache(groups[i]); var cache = cacheService.getActiveCache(groups[i]);
cache.discard(); cache.discard();
} }
} }
pm.removePermission(perm); // remove the permission
var pm = Components.classes["@mozilla.org/permissionmanager;1"]
.getService(Components.interfaces.nsIPermissionManager);
let uri;
try {
// file:// URIs are stored with their scheme. We try to parse them first, as
// URIs like http://file:///foo/bar/baz.html will parse as HTTP URIs.
uri = ios.newURI(host, null, null);
} catch (e) {
uri = ios.newURI("http://" + host, null, null);
}
pm.remove(uri, "offline-app");
list.removeChild(item); list.removeChild(item);
gAdvancedPane.offlineAppSelected(); gAdvancedPane.offlineAppSelected();

View File

@ -502,7 +502,7 @@ var gAdvancedPane = {
var usage = 0; var usage = 0;
for (var i = 0; i < groups.length; i++) { for (var i = 0; i < groups.length; i++) {
var uri = ios.newURI(groups[i], null, null); var uri = ios.newURI(groups[i], null, null);
if (perm.matchesURI(uri, true)) { if (uri.asciiHost == perm.host) {
var cache = cacheService.getActiveCache(groups[i]); var cache = cacheService.getActiveCache(groups[i]);
usage += cache.usage; usage += cache.usage;
} }
@ -544,7 +544,7 @@ var gAdvancedPane = {
var row = document.createElement("listitem"); var row = document.createElement("listitem");
row.id = ""; row.id = "";
row.className = "offlineapp"; row.className = "offlineapp";
row.setAttribute("origin", perm.principal.origin); row.setAttribute("host", perm.host);
var converted = DownloadUtils. var converted = DownloadUtils.
convertByteUnits(this._getOfflineAppUsage(perm, groups)); convertByteUnits(this._getOfflineAppUsage(perm, groups));
row.setAttribute("usage", row.setAttribute("usage",
@ -570,8 +570,7 @@ var gAdvancedPane = {
{ {
var list = document.getElementById("offlineAppsList"); var list = document.getElementById("offlineAppsList");
var item = list.selectedItem; var item = list.selectedItem;
var origin = item.getAttribute("origin"); var host = item.getAttribute("host");
var principal = BrowserUtils.principalFromOrigin(origin);
var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"] var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Components.interfaces.nsIPromptService); .getService(Components.interfaces.nsIPromptService);
@ -580,18 +579,13 @@ var gAdvancedPane = {
var bundle = document.getElementById("bundlePreferences"); var bundle = document.getElementById("bundlePreferences");
var title = bundle.getString("offlineAppRemoveTitle"); var title = bundle.getString("offlineAppRemoveTitle");
var prompt = bundle.getFormattedString("offlineAppRemovePrompt", [principal.URI.prePath]); var prompt = bundle.getFormattedString("offlineAppRemovePrompt", [host]);
var confirm = bundle.getString("offlineAppRemoveConfirm"); var confirm = bundle.getString("offlineAppRemoveConfirm");
var result = prompts.confirmEx(window, title, prompt, flags, confirm, var result = prompts.confirmEx(window, title, prompt, flags, confirm,
null, null, null, {}); null, null, null, {});
if (result != 0) if (result != 0)
return; return;
// get the permission
var pm = Components.classes["@mozilla.org/permissionmanager;1"]
.getService(Components.interfaces.nsIPermissionManager);
var perm = pm.getPermissionObject(principal, "offline-app");
// clear offline cache entries // clear offline cache entries
try { try {
var cacheService = Components.classes["@mozilla.org/network/application-cache-service;1"]. var cacheService = Components.classes["@mozilla.org/network/application-cache-service;1"].
@ -600,15 +594,26 @@ var gAdvancedPane = {
getService(Components.interfaces.nsIIOService); getService(Components.interfaces.nsIIOService);
var groups = cacheService.getGroups(); var groups = cacheService.getGroups();
for (var i = 0; i < groups.length; i++) { for (var i = 0; i < groups.length; i++) {
var uri = ios.newURI(groups[i], null, null); let uri = ios.newURI(groups[i], null, null);
if (perm.matchesURI(uri, true)) { if (uri.asciiHost == host) {
var cache = cacheService.getActiveCache(groups[i]); var cache = cacheService.getActiveCache(groups[i]);
cache.discard(); cache.discard();
} }
} }
} catch (e) {} } catch (e) {}
pm.removePermission(perm); // remove the permission
var pm = Components.classes["@mozilla.org/permissionmanager;1"]
.getService(Components.interfaces.nsIPermissionManager);
let uri;
try {
// file:// URIs are stored with their scheme. We try to parse them first, as
// URIs like http://file:///foo/bar/baz.html will parse as HTTP URIs.
uri = ios.newURI(host, null, null);
} catch (e) {
uri = ios.newURI("http://" + host, null, null);
}
pm.remove(uri, "offline-app");
list.removeChild(item); list.removeChild(item);
gAdvancedPane.offlineAppSelected(); gAdvancedPane.offlineAppSelected();

View File

@ -9,10 +9,10 @@ const nsICookiePermission = Components.interfaces.nsICookiePermission;
const NOTIFICATION_FLUSH_PERMISSIONS = "flush-pending-permissions"; const NOTIFICATION_FLUSH_PERMISSIONS = "flush-pending-permissions";
function Permission(principal, type, capability) function Permission(host, rawHost, type, capability)
{ {
this.principal = principal; this.host = host;
this.origin = principal.origin; this.rawHost = rawHost;
this.type = type; this.type = type;
this.capability = capability; this.capability = capability;
} }
@ -35,7 +35,7 @@ var gPermissionManager = {
getCellText: function (aRow, aColumn) getCellText: function (aRow, aColumn)
{ {
if (aColumn.id == "siteCol") if (aColumn.id == "siteCol")
return gPermissionManager._permissions[aRow].origin; return gPermissionManager._permissions[aRow].rawHost;
else if (aColumn.id == "statusCol") else if (aColumn.id == "statusCol")
return gPermissionManager._permissions[aRow].capability; return gPermissionManager._permissions[aRow].capability;
return ""; return "";
@ -82,17 +82,10 @@ var gPermissionManager = {
addPermission: function (aCapability) addPermission: function (aCapability)
{ {
var textbox = document.getElementById("url"); var textbox = document.getElementById("url");
var input_url = textbox.value.replace(/^\s*/, ""); // trim any leading space var host = textbox.value.replace(/^\s*([-\w]*:\/+)?/, ""); // trim any leading space and scheme
let principal;
try { try {
// If the uri doesn't successfully parse, try adding a http:// and parsing again var uri = Services.io.newURI("http://"+host, null, null);
let uri; host = uri.host;
try {
let uri = Services.io.newURI(input_url, null, null);
} catch(ex) {
uri = Services.io.newURI("http://" + input_url, null, null);
}
principal = Services.scriptSecurityManager.getNoAppCodebasePrincipal(uri);
} catch(ex) { } catch(ex) {
var message = this._bundle.getString("invalidURI"); var message = this._bundle.getString("invalidURI");
var title = this._bundle.getString("invalidURITitle"); var title = this._bundle.getString("invalidURITitle");
@ -103,11 +96,11 @@ var gPermissionManager = {
var capabilityString = this._getCapabilityString(aCapability); var capabilityString = this._getCapabilityString(aCapability);
// check whether the permission already exists, if not, add it // check whether the permission already exists, if not, add it
let permissionExists = false; let hostExists = false;
let capabilityExists = false; let capabilityExists = false;
for (var i = 0; i < this._permissions.length; ++i) { for (var i = 0; i < this._permissions.length; ++i) {
if (this._permissions[i].principal.equals(principal)) { if (this._permissions[i].rawHost == host) {
permissionExists = true; hostExists = true;
capabilityExists = this._permissions[i].capability == capabilityString; capabilityExists = this._permissions[i].capability == capabilityString;
if (!capabilityExists) { if (!capabilityExists) {
this._permissions[i].capability = capabilityString; this._permissions[i].capability = capabilityString;
@ -116,14 +109,14 @@ var gPermissionManager = {
} }
} }
let permissionParams = {principal: principal, type: this._type, capability: aCapability}; let permissionParams = {host: host, type: this._type, capability: aCapability};
if (!permissionExists) { if (!hostExists) {
this._permissionsToAdd.set(principal.origin, permissionParams); this._permissionsToAdd.set(host, permissionParams);
this._addPermission(permissionParams); this._addPermission(permissionParams);
} }
else if (!capabilityExists) { else if (!capabilityExists) {
this._permissionsToAdd.set(principal.origin, permissionParams); this._permissionsToAdd.set(host, permissionParams);
this._handleCapabilityChange(); this._handleCapabilityChange();
} }
textbox.value = ""; textbox.value = "";
@ -138,15 +131,15 @@ var gPermissionManager = {
_removePermission: function(aPermission) _removePermission: function(aPermission)
{ {
this._removePermissionFromList(aPermission.principal); this._removePermissionFromList(aPermission.host);
// If this permission was added during this session, let's remove // If this permission was added during this session, let's remove
// it from the pending adds list to prevent calls to the // it from the pending adds list to prevent calls to the
// permission manager. // permission manager.
let isNewPermission = this._permissionsToAdd.delete(aPermission.principal.origin); let isNewPermission = this._permissionsToAdd.delete(aPermission.host);
if (!isNewPermission) { if (!isNewPermission) {
this._permissionsToDelete.set(aPermission.principal.origin, aPermission); this._permissionsToDelete.set(aPermission.host, aPermission);
} }
}, },
@ -283,7 +276,7 @@ var gPermissionManager = {
} }
else if (aData == "changed") { else if (aData == "changed") {
for (var i = 0; i < this._permissions.length; ++i) { for (var i = 0; i < this._permissions.length; ++i) {
if (permission.matches(this._permissions[i].principal, true)) { if (this._permissions[i].host == permission.host) {
this._permissions[i].capability = this._getCapabilityString(permission.capability); this._permissions[i].capability = this._getCapabilityString(permission.capability);
break; break;
} }
@ -370,11 +363,13 @@ var gPermissionManager = {
this.uninit(); this.uninit();
for (let permissionParams of this._permissionsToAdd.values()) { for (let permissionParams of this._permissionsToAdd.values()) {
Services.perms.addFromPrincipal(permissionParams.principal, permissionParams.type, permissionParams.capability); let uri = Services.io.newURI("http://" + permissionParams.host, null, null);
Services.perms.add(uri, permissionParams.type, permissionParams.capability);
} }
for (let p of this._permissionsToDelete.values()) { for (let p of this._permissionsToDelete.values()) {
Services.perms.removeFromPrincipal(p.principal, p.type); let uri = Services.io.newURI("http://" + p.host, null, null);
Services.perms.remove(uri, p.type);
} }
window.close(); window.close();
@ -397,7 +392,7 @@ var gPermissionManager = {
// sort and display the table // sort and display the table
this._tree.view = this._view; this._tree.view = this._view;
this.onPermissionSort("origin"); this.onPermissionSort("rawHost");
// disable "remove all" button if there are none // disable "remove all" button if there are none
document.getElementById("removeAllPermissions").disabled = this._permissions.length == 0; document.getElementById("removeAllPermissions").disabled = this._permissions.length == 0;
@ -409,19 +404,20 @@ var gPermissionManager = {
(!this._manageCapability || (!this._manageCapability ||
(aPermission.capability == this._manageCapability))) { (aPermission.capability == this._manageCapability))) {
var principal = aPermission.principal; var host = aPermission.host;
var capabilityString = this._getCapabilityString(aPermission.capability); var capabilityString = this._getCapabilityString(aPermission.capability);
var p = new Permission(principal, var p = new Permission(host,
(host.charAt(0) == ".") ? host.substring(1,host.length) : host,
aPermission.type, aPermission.type,
capabilityString); capabilityString);
this._permissions.push(p); this._permissions.push(p);
} }
}, },
_removePermissionFromList: function (aPrincipal) _removePermissionFromList: function (aHost)
{ {
for (let i = 0; i < this._permissions.length; ++i) { for (let i = 0; i < this._permissions.length; ++i) {
if (this._permissions[i].principal.equals(aPrincipal)) { if (this._permissions[i].host == aHost) {
this._permissions.splice(i, 1); this._permissions.splice(i, 1);
this._view._rowCount--; this._view._rowCount--;
this._tree.treeBoxObject.rowCountChanged(this._view.rowCount - 1, -1); this._tree.treeBoxObject.rowCountChanged(this._view.rowCount - 1, -1);
@ -431,15 +427,15 @@ var gPermissionManager = {
} }
}, },
setOrigin: function (aOrigin) setHost: function (aHost)
{ {
document.getElementById("url").value = aOrigin; document.getElementById("url").value = aHost;
} }
}; };
function setOrigin(aOrigin) function setHost(aHost)
{ {
gPermissionManager.setOrigin(aOrigin); gPermissionManager.setHost(aHost);
} }
function initWithParams(aParams) function initWithParams(aParams)

View File

@ -103,11 +103,11 @@ var tests = [
sitesFilter.doCommand(); sitesFilter.doCommand();
}, },
run: function() { run: function() {
let testSite1 = getSiteItem(TEST_URI_1.prePath); let testSite1 = getSiteItem(TEST_URI_1.host);
ok(testSite1.collapsed, "test site 1 is collapsed after early filtering"); ok(testSite1.collapsed, "test site 1 is collapsed after early filtering");
let testSite2 = getSiteItem(TEST_URI_2.prePath); let testSite2 = getSiteItem(TEST_URI_2.host);
ok(!testSite2.collapsed, "test site 2 is not collapsed after early filtering"); ok(!testSite2.collapsed, "test site 2 is not collapsed after early filtering");
let testSite3 = getSiteItem(TEST_URI_3.prePath); let testSite3 = getSiteItem(TEST_URI_3.host);
ok(testSite3.collapsed, "test site 3 is collapsed after early filtering"); ok(testSite3.collapsed, "test site 3 is collapsed after early filtering");
runNextTest(); runNextTest();
@ -119,11 +119,11 @@ var tests = [
ForgetAboutSite.removeDataFromDomain(TEST_URI_2.host); ForgetAboutSite.removeDataFromDomain(TEST_URI_2.host);
}, },
run: function() { run: function() {
let testSite1 = getSiteItem(TEST_URI_1.prePath); let testSite1 = getSiteItem(TEST_URI_1.host);
ok(testSite1, "test site 1 was not removed from sites list"); ok(testSite1, "test site 1 was not removed from sites list");
let testSite2 = getSiteItem(TEST_URI_2.prePath); let testSite2 = getSiteItem(TEST_URI_2.host);
ok(!testSite2, "test site 2 was pre-removed from sites list"); ok(!testSite2, "test site 2 was pre-removed from sites list");
let testSite3 = getSiteItem(TEST_URI_3.prePath); let testSite3 = getSiteItem(TEST_URI_3.host);
ok(testSite3, "test site 3 was not removed from sites list"); ok(testSite3, "test site 3 was not removed from sites list");
runNextTest(); runNextTest();
@ -131,7 +131,7 @@ var tests = [
} }
]; ];
function getSiteItem(aPrePath) { function getSiteItem(aHost) {
return gBrowser.contentDocument. return gBrowser.contentDocument.
querySelector(".site[value='" + aPrePath + "']"); querySelector(".site[value='" + aHost + "']");
} }

View File

@ -20,7 +20,7 @@ var testRunner = {
"permission text should be set correctly"); "permission text should be set correctly");
params.btnApplyChanges.doCommand(); params.btnApplyChanges.doCommand();
}, },
observances: [{ type: "cookie", origin: "http://test.com", data: "added", observances: [{ type: "cookie", host: "test.com", data: "added",
capability: Ci.nsIPermissionManager.ALLOW_ACTION }], capability: Ci.nsIPermissionManager.ALLOW_ACTION }],
}, },
{ {
@ -31,7 +31,7 @@ var testRunner = {
"permission should change to deny in UI"); "permission should change to deny in UI");
params.btnApplyChanges.doCommand(); params.btnApplyChanges.doCommand();
}, },
observances: [{ type: "cookie", origin: "http://test.com", data: "changed", observances: [{ type: "cookie", host: "test.com", data: "changed",
capability: Ci.nsIPermissionManager.DENY_ACTION }], capability: Ci.nsIPermissionManager.DENY_ACTION }],
}, },
{ {
@ -42,7 +42,7 @@ var testRunner = {
"permission should revert back to allow"); "permission should revert back to allow");
params.btnApplyChanges.doCommand(); params.btnApplyChanges.doCommand();
}, },
observances: [{ type: "cookie", origin: "http://test.com", data: "changed", observances: [{ type: "cookie", host: "test.com", data: "changed",
capability: Ci.nsIPermissionManager.ALLOW_ACTION }], capability: Ci.nsIPermissionManager.ALLOW_ACTION }],
}, },
{ {
@ -52,7 +52,7 @@ var testRunner = {
is(params.tree.view.rowCount, 0, "exception should be removed"); is(params.tree.view.rowCount, 0, "exception should be removed");
params.btnApplyChanges.doCommand(); params.btnApplyChanges.doCommand();
}, },
observances: [{ type: "cookie", origin: "http://test.com", data: "deleted" }], observances: [{ type: "cookie", host: "test.com", data: "deleted" }],
}, },
{ {
test: function(params) { test: function(params) {
@ -61,7 +61,7 @@ var testRunner = {
is(params.tree.view.rowCount, 0, "adding unrelated permission should not change display"); is(params.tree.view.rowCount, 0, "adding unrelated permission should not change display");
params.btnApplyChanges.doCommand(); params.btnApplyChanges.doCommand();
}, },
observances: [{ type: "popup", origin: "http://test.com", data: "added", observances: [{ type: "popup", host: "test.com", data: "added",
capability: Ci.nsIPermissionManager.DENY_ACTION }], capability: Ci.nsIPermissionManager.DENY_ACTION }],
cleanUp: function(params) { cleanUp: function(params) {
let uri = params.ioService.newURI("http://test.com", null, null); let uri = params.ioService.newURI("http://test.com", null, null);
@ -160,17 +160,12 @@ var testRunner = {
let expected = testRunner.tests[testRunner._currentTest].observances.shift(); let expected = testRunner.tests[testRunner._currentTest].observances.shift();
is(aData, expected.data, "type of message should be the same"); is(aData, expected.data, "type of message should be the same");
for each (let prop in ["type", "capability"]) { for each (let prop in ["type", "host", "capability"]) {
if (expected[prop]) if (expected[prop])
is(permission[prop], expected[prop], is(permission[prop], expected[prop],
"property: \"" + prop + "\" should be equal"); "property: \"" + prop + "\" should be equal");
} }
if (expected.origin) {
is(permission.principal.origin, expected.origin,
"property: \"origin\" should be equal");
}
os.removeObserver(permObserver, "perm-changed"); os.removeObserver(permObserver, "perm-changed");
if (testRunner.tests[testRunner._currentTest].cleanup) { if (testRunner.tests[testRunner._currentTest].cleanup) {

View File

@ -115,8 +115,8 @@ var tests = [
is(gSitesList.firstChild.id, "all-sites-item", is(gSitesList.firstChild.id, "all-sites-item",
"all sites is the first item in the sites list"); "all sites is the first item in the sites list");
ok(getSiteItem(TEST_URI_1.prePath), "site item from places db exists"); ok(getSiteItem(TEST_URI_1.host), "site item from places db exists");
ok(getSiteItem(TEST_URI_2.prePath), "site item from enumerating services exists"); ok(getSiteItem(TEST_URI_2.host), "site item from enumerating services exists");
runNextTest(); runNextTest();
}, },
@ -128,9 +128,9 @@ var tests = [
sitesFilter.doCommand(); sitesFilter.doCommand();
// make sure correct sites are collapsed/showing // make sure correct sites are collapsed/showing
let testSite1 = getSiteItem(TEST_URI_1.prePath); let testSite1 = getSiteItem(TEST_URI_1.host);
ok(!testSite1.collapsed, "test site 1 is not collapsed"); ok(!testSite1.collapsed, "test site 1 is not collapsed");
let testSite2 = getSiteItem(TEST_URI_2.prePath); let testSite2 = getSiteItem(TEST_URI_2.host);
ok(testSite2.collapsed, "test site 2 is collapsed"); ok(testSite2.collapsed, "test site 2 is collapsed");
// clear filter // clear filter
@ -202,13 +202,13 @@ var tests = [
function test_select_site() { function test_select_site() {
// select the site that has the permissions we set at the beginning of the test // select the site that has the permissions we set at the beginning of the test
let testSiteItem = getSiteItem(TEST_URI_2.prePath); let testSiteItem = getSiteItem(TEST_URI_2.host);
gSitesList.selectedItem = testSiteItem; gSitesList.selectedItem = testSiteItem;
let siteHeader = gBrowser.contentDocument.getElementById("site-header"); let siteHeader = gBrowser.contentDocument.getElementById("site-header");
is(siteHeader, gHeaderDeck.selectedPanel, is(siteHeader, gHeaderDeck.selectedPanel,
"correct header shown for a specific site"); "correct header shown for a specific site");
is(gSiteLabel.value, TEST_URI_2.prePath, "header updated for selected site"); is(gSiteLabel.value, TEST_URI_2.host, "header updated for selected site");
ok(!gBrowser.contentDocument.getElementById("passwords-count").hidden, ok(!gBrowser.contentDocument.getElementById("passwords-count").hidden,
"passwords count is not hidden"); "passwords count is not hidden");
@ -283,7 +283,7 @@ var tests = [
"all sites item selected after forgetting selected site"); "all sites item selected after forgetting selected site");
// check to make sure site is gone from sites list // check to make sure site is gone from sites list
let testSiteItem = getSiteItem(TEST_URI_2.prePath); let testSiteItem = getSiteItem(TEST_URI_2.host);
ok(!testSiteItem, "site removed from sites list"); ok(!testSiteItem, "site removed from sites list");
// check to make sure we forgot all permissions corresponding to site // check to make sure we forgot all permissions corresponding to site

View File

@ -9,7 +9,6 @@ const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/BrowserUtils.jsm");
XPCOMUtils.defineLazyGetter(this, "gLangBundle", () => XPCOMUtils.defineLazyGetter(this, "gLangBundle", () =>
Services.strings.createBundle("chrome://global/locale/languageNames.properties")); Services.strings.createBundle("chrome://global/locale/languageNames.properties"));
@ -84,7 +83,7 @@ let gTranslationExceptions = {
if (perm.type == kPermissionType && if (perm.type == kPermissionType &&
perm.capability == Services.perms.DENY_ACTION) { perm.capability == Services.perms.DENY_ACTION) {
this._sites.push(perm.principal.origin); this._sites.push(perm.host);
} }
} }
Services.obs.addObserver(this, "perm-changed", false); Services.obs.addObserver(this, "perm-changed", false);
@ -127,14 +126,14 @@ let gTranslationExceptions = {
if (aData == "added") { if (aData == "added") {
if (perm.capability != Services.perms.DENY_ACTION) if (perm.capability != Services.perms.DENY_ACTION)
return; return;
this._sites.push(perm.principal.origin); this._sites.push(perm.host);
this._sites.sort(); this._sites.sort();
let boxObject = this._siteTree.boxObject; let boxObject = this._siteTree.boxObject;
boxObject.rowCountChanged(0, 1); boxObject.rowCountChanged(0, 1);
boxObject.invalidate(); boxObject.invalidate();
} }
else if (aData == "deleted") { else if (aData == "deleted") {
let index = this._sites.indexOf(perm.principal.origin); let index = this._sites.indexOf(perm.host);
if (index == -1) if (index == -1)
return; return;
this._sites.splice(index, 1); this._sites.splice(index, 1);
@ -189,9 +188,9 @@ let gTranslationExceptions = {
onSiteDeleted: function() { onSiteDeleted: function() {
let removedSites = this._siteTree.getSelectedItems(); let removedSites = this._siteTree.getSelectedItems();
for (let origin of removedSites) { for (let host of removedSites) {
let principal = BrowserUtils.principalFromOrigin(origin); let uri = Services.io.newURI("http://" + host, null, null);
Services.perms.removeFromPrincipal(principal, kPermissionType); Services.perms.remove(uri, kPermissionType);
} }
}, },
@ -202,9 +201,9 @@ let gTranslationExceptions = {
let removedSites = this._sites.splice(0, this._sites.length); let removedSites = this._sites.splice(0, this._sites.length);
this._siteTree.boxObject.rowCountChanged(0, -removedSites.length); this._siteTree.boxObject.rowCountChanged(0, -removedSites.length);
for (let origin of removedSites) { for (let host of removedSites) {
let principal = BrowserUtils.principalFromOrigin(origin); let uri = Services.io.newURI("http://" + host, null, null);
Services.perms.removeFromPrincipal(principal, kPermissionType); Services.perms.remove(uri, kPermissionType);
} }
this.onSiteSelected(); this.onSiteSelected();

View File

@ -51,7 +51,7 @@ function getDomainExceptions() {
if (perm.type == "translate" && if (perm.type == "translate" &&
perm.capability == Services.perms.DENY_ACTION) perm.capability == Services.perms.DENY_ACTION)
results.push(perm.principal); results.push(perm.host);
} }
return results; return results;
@ -181,7 +181,7 @@ let gTests = [
// Check this has been saved to the exceptions list. // Check this has been saved to the exceptions list.
let sites = getDomainExceptions(); let sites = getDomainExceptions();
is(sites.length, 1, "one site in the exception list"); is(sites.length, 1, "one site in the exception list");
is(sites[0].origin, "http://example.com", "correct site in the exception list"); is(sites[0], "example.com", "correct site in the exception list");
ok(!ui.shouldShowInfoBar(uri, "fr"), ok(!ui.shouldShowInfoBar(uri, "fr"),
"the infobar wouldn't be shown anymore"); "the infobar wouldn't be shown anymore");

View File

@ -198,10 +198,8 @@ function loadUITourTestPage(callback, host = "https://example.com/") {
function UITourTest() { function UITourTest() {
Services.prefs.setBoolPref("browser.uitour.enabled", true); Services.prefs.setBoolPref("browser.uitour.enabled", true);
let testHttpsUri = Services.io.newURI("https://example.com", null, null); let testUri = Services.io.newURI("http://example.com", null, null);
let testHttpUri = Services.io.newURI("http://example.com", null, null); Services.perms.add(testUri, "uitour", Services.perms.ALLOW_ACTION);
Services.perms.add(testHttpsUri, "uitour", Services.perms.ALLOW_ACTION);
Services.perms.add(testHttpUri, "uitour", Services.perms.ALLOW_ACTION);
waitForExplicitFinish(); waitForExplicitFinish();
@ -212,8 +210,7 @@ function UITourTest() {
gBrowser.removeTab(gTestTab); gBrowser.removeTab(gTestTab);
delete window.gTestTab; delete window.gTestTab;
Services.prefs.clearUserPref("browser.uitour.enabled", true); Services.prefs.clearUserPref("browser.uitour.enabled", true);
Services.perms.remove(testHttpsUri, "uitour"); Services.perms.remove(testUri, "uitour");
Services.perms.remove(testHttpUri, "uitour");
}); });
function done() { function done() {

View File

@ -695,6 +695,20 @@ PluginContent.prototype = {
this._showClickToPlayNotification(null, false); this._showClickToPlayNotification(null, false);
}, },
// Match the behaviour of nsPermissionManager
_getHostFromPrincipal: function (principal) {
if (!principal.URI || principal.URI.schemeIs("moz-nullprincipal")) {
return "(null)";
}
try {
if (principal.URI.host)
return principal.URI.host;
} catch (e) {}
return principal.origin;
},
/** /**
* Activate the plugins that the user has specified. * Activate the plugins that the user has specified.
*/ */
@ -762,6 +776,7 @@ PluginContent.prototype = {
let pluginData = this.pluginData; let pluginData = this.pluginData;
let principal = this.content.document.nodePrincipal; let principal = this.content.document.nodePrincipal;
let principalHost = this._getHostFromPrincipal(principal);
let location = this.content.document.location.href; let location = this.content.document.location.href;
for (let p of plugins) { for (let p of plugins) {
@ -777,11 +792,11 @@ PluginContent.prototype = {
let permissionObj = Services.perms. let permissionObj = Services.perms.
getPermissionObject(principal, pluginInfo.permissionString, false); getPermissionObject(principal, pluginInfo.permissionString, false);
if (permissionObj) { if (permissionObj) {
pluginInfo.pluginPermissionPrePath = permissionObj.principal.originNoSuffix; pluginInfo.pluginPermissionHost = permissionObj.host;
pluginInfo.pluginPermissionType = permissionObj.expireType; pluginInfo.pluginPermissionType = permissionObj.expireType;
} }
else { else {
pluginInfo.pluginPermissionPrePath = principal.originNoSuffix; pluginInfo.pluginPermissionHost = principalHost;
pluginInfo.pluginPermissionType = undefined; pluginInfo.pluginPermissionType = undefined;
} }
@ -791,6 +806,7 @@ PluginContent.prototype = {
this.global.sendAsyncMessage("PluginContent:ShowClickToPlayNotification", { this.global.sendAsyncMessage("PluginContent:ShowClickToPlayNotification", {
plugins: [... this.pluginData.values()], plugins: [... this.pluginData.values()],
showNow: showNow, showNow: showNow,
host: principalHost,
location: location, location: location,
}, null, principal); }, null, principal);
}, },
@ -873,6 +889,7 @@ PluginContent.prototype = {
this.global.sendAsyncMessage("PluginContent:UpdateHiddenPluginUI", { this.global.sendAsyncMessage("PluginContent:UpdateHiddenPluginUI", {
haveInsecure: haveInsecure, haveInsecure: haveInsecure,
actions: [... actions.values()], actions: [... actions.values()],
host: this._getHostFromPrincipal(principal),
location: location, location: location,
}, null, principal); }, null, principal);
}, },

View File

@ -51,7 +51,7 @@ OriginAttributes::CreateSuffix(nsACString& aStr) const
params->Serialize(value); params->Serialize(value);
if (!value.IsEmpty()) { if (!value.IsEmpty()) {
aStr.AppendLiteral("^"); aStr.AppendLiteral("!");
aStr.Append(NS_ConvertUTF16toUTF8(value)); aStr.Append(NS_ConvertUTF16toUTF8(value));
} }
} }
@ -117,7 +117,7 @@ OriginAttributes::PopulateFromSuffix(const nsACString& aStr)
return true; return true;
} }
if (aStr[0] != '^') { if (aStr[0] != '!') {
return false; return false;
} }
@ -134,7 +134,7 @@ OriginAttributes::PopulateFromOrigin(const nsACString& aOrigin,
{ {
// RFindChar is only available on nsCString. // RFindChar is only available on nsCString.
nsCString origin(aOrigin); nsCString origin(aOrigin);
int32_t pos = origin.RFindChar('^'); int32_t pos = origin.RFindChar('!');
if (pos == kNotFound) { if (pos == kNotFound) {
aOriginNoSuffix = origin; aOriginNoSuffix = origin;

View File

@ -14,7 +14,6 @@
#include "pratom.h" #include "pratom.h"
#include "nsIURI.h" #include "nsIURI.h"
#include "nsIURL.h" #include "nsIURL.h"
#include "nsIStandardURL.h"
#include "nsIURIWithPrincipal.h" #include "nsIURIWithPrincipal.h"
#include "nsJSPrincipals.h" #include "nsJSPrincipals.h"
#include "nsIEffectiveTLDService.h" #include "nsIEffectiveTLDService.h"
@ -128,31 +127,6 @@ nsPrincipal::GetOriginForURI(nsIURI* aURI, nsACString& aOrigin)
} }
} }
// We want the invariant that prinA.origin == prinB.origin i.f.f.
// prinA.equals(prinB). However, this requires that we impose certain constraints
// on the behavior and origin semantics of principals, and in particular, forbid
// creating origin strings for principals whose equality constraints are not
// expressible as strings (i.e. object equality). Moreover, we want to forbid URIs
// containing the magic "^" we use as a separating character for origin
// attributes.
//
// These constraints can generally be achieved by restricting .origin to
// nsIStandardURL-based URIs, but there are a few other URI schemes that we need
// to handle.
bool isBehaved;
if ((NS_SUCCEEDED(origin->SchemeIs("about", &isBehaved)) && isBehaved) ||
(NS_SUCCEEDED(origin->SchemeIs("moz-safe-about", &isBehaved)) && isBehaved) ||
(NS_SUCCEEDED(origin->SchemeIs("indexeddb", &isBehaved)) && isBehaved)) {
rv = origin->GetAsciiSpec(aOrigin);
NS_ENSURE_SUCCESS(rv, rv);
// These URIs could technically contain a '^', but they never should.
if (NS_WARN_IF(aOrigin.FindChar('^', 0) != -1)) {
aOrigin.Truncate();
return NS_ERROR_FAILURE;
}
return NS_OK;
}
int32_t port; int32_t port;
if (NS_SUCCEEDED(rv) && !isChrome) { if (NS_SUCCEEDED(rv) && !isChrome) {
rv = origin->GetPort(&port); rv = origin->GetPort(&port);
@ -170,14 +144,6 @@ nsPrincipal::GetOriginForURI(nsIURI* aURI, nsACString& aOrigin)
aOrigin.Append(hostPort); aOrigin.Append(hostPort);
} }
else { else {
// If we reached this branch, we can only create an origin if we have a nsIStandardURL.
// So, we query to a nsIStandardURL, and fail if we aren't an instance of an nsIStandardURL
// nsIStandardURLs have the good property of escaping the '^' character in their specs,
// which means that we can be sure that the caret character (which is reserved for delimiting
// the end of the spec, and the beginning of the origin attributes) is not present in the
// origin string
nsCOMPtr<nsIStandardURL> standardURL = do_QueryInterface(origin);
NS_ENSURE_TRUE(standardURL, NS_ERROR_FAILURE);
rv = origin->GetAsciiSpec(aOrigin); rv = origin->GetAsciiSpec(aOrigin);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
} }

View File

@ -68,33 +68,33 @@ function run_test() {
// Just app. // Just app.
var exampleOrg_app = ssm.createCodebasePrincipal(makeURI('http://example.org'), {appId: 42}); var exampleOrg_app = ssm.createCodebasePrincipal(makeURI('http://example.org'), {appId: 42});
var nullPrin_app = ssm.createNullPrincipal({appId: 42}); var nullPrin_app = ssm.createNullPrincipal({appId: 42});
checkOriginAttributes(exampleOrg_app, {appId: 42}, '^appId=42'); checkOriginAttributes(exampleOrg_app, {appId: 42}, '!appId=42');
checkOriginAttributes(nullPrin_app, {appId: 42}, '^appId=42'); checkOriginAttributes(nullPrin_app, {appId: 42}, '!appId=42');
do_check_eq(exampleOrg_app.origin, 'http://example.org^appId=42'); do_check_eq(exampleOrg_app.origin, 'http://example.org!appId=42');
// Just browser. // Just browser.
var exampleOrg_browser = ssm.createCodebasePrincipal(makeURI('http://example.org'), {inBrowser: true}); var exampleOrg_browser = ssm.createCodebasePrincipal(makeURI('http://example.org'), {inBrowser: true});
var nullPrin_browser = ssm.createNullPrincipal({inBrowser: true}); var nullPrin_browser = ssm.createNullPrincipal({inBrowser: true});
checkOriginAttributes(exampleOrg_browser, {inBrowser: true}, '^inBrowser=1'); checkOriginAttributes(exampleOrg_browser, {inBrowser: true}, '!inBrowser=1');
checkOriginAttributes(nullPrin_browser, {inBrowser: true}, '^inBrowser=1'); checkOriginAttributes(nullPrin_browser, {inBrowser: true}, '!inBrowser=1');
do_check_eq(exampleOrg_browser.origin, 'http://example.org^inBrowser=1'); do_check_eq(exampleOrg_browser.origin, 'http://example.org!inBrowser=1');
// App and browser. // App and browser.
var exampleOrg_appBrowser = ssm.createCodebasePrincipal(makeURI('http://example.org'), {inBrowser: true, appId: 42}); var exampleOrg_appBrowser = ssm.createCodebasePrincipal(makeURI('http://example.org'), {inBrowser: true, appId: 42});
var nullPrin_appBrowser = ssm.createNullPrincipal({inBrowser: true, appId: 42}); var nullPrin_appBrowser = ssm.createNullPrincipal({inBrowser: true, appId: 42});
checkOriginAttributes(exampleOrg_appBrowser, {appId: 42, inBrowser: true}, '^appId=42&inBrowser=1'); checkOriginAttributes(exampleOrg_appBrowser, {appId: 42, inBrowser: true}, '!appId=42&inBrowser=1');
checkOriginAttributes(nullPrin_appBrowser, {appId: 42, inBrowser: true}, '^appId=42&inBrowser=1'); checkOriginAttributes(nullPrin_appBrowser, {appId: 42, inBrowser: true}, '!appId=42&inBrowser=1');
do_check_eq(exampleOrg_appBrowser.origin, 'http://example.org^appId=42&inBrowser=1'); do_check_eq(exampleOrg_appBrowser.origin, 'http://example.org!appId=42&inBrowser=1');
// App and browser, different domain. // App and browser, different domain.
var exampleCom_appBrowser = ssm.createCodebasePrincipal(makeURI('https://www.example.com:123'), {appId: 42, inBrowser: true}); var exampleCom_appBrowser = ssm.createCodebasePrincipal(makeURI('https://www.example.com:123'), {appId: 42, inBrowser: true});
checkOriginAttributes(exampleCom_appBrowser, {appId: 42, inBrowser: true}, '^appId=42&inBrowser=1'); checkOriginAttributes(exampleCom_appBrowser, {appId: 42, inBrowser: true}, '!appId=42&inBrowser=1');
do_check_eq(exampleCom_appBrowser.origin, 'https://www.example.com:123^appId=42&inBrowser=1'); do_check_eq(exampleCom_appBrowser.origin, 'https://www.example.com:123!appId=42&inBrowser=1');
// Addon. // Addon.
var exampleOrg_addon = ssm.createCodebasePrincipal(makeURI('http://example.org'), {addonId: 'dummy'}); var exampleOrg_addon = ssm.createCodebasePrincipal(makeURI('http://example.org'), {addonId: 'dummy'});
checkOriginAttributes(exampleOrg_addon, { addonId: "dummy" }, '^addonId=dummy'); checkOriginAttributes(exampleOrg_addon, { addonId: "dummy" }, '!addonId=dummy');
do_check_eq(exampleOrg_addon.origin, 'http://example.org^addonId=dummy'); do_check_eq(exampleOrg_addon.origin, 'http://example.org!addonId=dummy');
// Check that all of the above are cross-origin. // Check that all of the above are cross-origin.
checkCrossOrigin(exampleOrg_app, exampleOrg); checkCrossOrigin(exampleOrg_app, exampleOrg);

View File

@ -51,7 +51,7 @@ add_test(() => {
}); });
Assert.ok(mozapp.principal, "app principal should exist"); Assert.ok(mozapp.principal, "app principal should exist");
let expectedPrincipalOrigin = app.origin + "^appId=" + app.localId; let expectedPrincipalOrigin = app.origin + "!appId=" + app.localId;
Assert.equal(mozapp.principal.origin, expectedPrincipalOrigin, Assert.equal(mozapp.principal.origin, expectedPrincipalOrigin,
"app principal origin ok"); "app principal origin ok");
Assert.equal(mozapp.principal.appId, app.localId, "app principal appId ok"); Assert.equal(mozapp.principal.appId, app.localId, "app principal appId ok");

View File

@ -53,7 +53,6 @@
#include "mozilla/plugins/PluginModuleParent.h" #include "mozilla/plugins/PluginModuleParent.h"
#include "mozilla/widget/WidgetMessageUtils.h" #include "mozilla/widget/WidgetMessageUtils.h"
#include "mozilla/media/MediaChild.h" #include "mozilla/media/MediaChild.h"
#include "mozilla/BasePrincipal.h"
#if defined(MOZ_CONTENT_SANDBOX) #if defined(MOZ_CONTENT_SANDBOX)
#if defined(XP_WIN) #if defined(XP_WIN)
@ -2113,15 +2112,18 @@ ContentChild::RecvAddPermission(const IPC::Permission& permission)
MOZ_ASSERT(permissionManager, MOZ_ASSERT(permissionManager,
"We have no permissionManager in the Content process !"); "We have no permissionManager in the Content process !");
nsAutoCString originNoSuffix;
OriginAttributes attrs;
attrs.PopulateFromOrigin(permission.origin, originNoSuffix);
nsCOMPtr<nsIURI> uri; nsCOMPtr<nsIURI> uri;
nsresult rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix); NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("http://") + nsCString(permission.host));
NS_ENSURE_SUCCESS(rv, true); NS_ENSURE_TRUE(uri, true);
nsCOMPtr<nsIPrincipal> principal = mozilla::BasePrincipal::CreateCodebasePrincipal(uri, attrs); nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
MOZ_ASSERT(secMan);
nsCOMPtr<nsIPrincipal> principal;
nsresult rv = secMan->GetAppCodebasePrincipal(uri, permission.appId,
permission.isInBrowserElement,
getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, true);
// child processes don't care about modification time. // child processes don't care about modification time.
int64_t modificationTime = 0; int64_t modificationTime = 0;

View File

@ -2559,12 +2559,12 @@ ContentParent::RecvReadPermissions(InfallibleTArray<IPC::Permission>* aPermissio
enumerator->GetNext(getter_AddRefs(supp)); enumerator->GetNext(getter_AddRefs(supp));
nsCOMPtr<nsIPermission> perm = do_QueryInterface(supp); nsCOMPtr<nsIPermission> perm = do_QueryInterface(supp);
nsCOMPtr<nsIPrincipal> principal; nsCString host;
perm->GetPrincipal(getter_AddRefs(principal)); perm->GetHost(host);
nsCString origin; uint32_t appId;
if (principal) { perm->GetAppId(&appId);
principal->GetOrigin(origin); bool isInBrowserElement;
} perm->GetIsInBrowserElement(&isInBrowserElement);
nsCString type; nsCString type;
perm->GetType(type); perm->GetType(type);
uint32_t capability; uint32_t capability;
@ -2574,7 +2574,8 @@ ContentParent::RecvReadPermissions(InfallibleTArray<IPC::Permission>* aPermissio
int64_t expireTime; int64_t expireTime;
perm->GetExpireTime(&expireTime); perm->GetExpireTime(&expireTime);
aPermissions->AppendElement(IPC::Permission(origin, type, aPermissions->AppendElement(IPC::Permission(host, appId,
isInBrowserElement, type,
capability, expireType, capability, expireType,
expireTime)); expireTime));
} }

View File

@ -196,20 +196,8 @@ DOMStorageObserver::Observe(nsISupports* aSubject,
return NS_OK; return NS_OK;
} }
nsCOMPtr<nsIPrincipal> principal;
perm->GetPrincipal(getter_AddRefs(principal));
if (!principal) {
return NS_OK;
}
nsCOMPtr<nsIURI> origin;
principal->GetURI(getter_AddRefs(origin));
if (!origin) {
return NS_OK;
}
nsAutoCString host; nsAutoCString host;
origin->GetHost(host); perm->GetHost(host);
if (host.IsEmpty()) { if (host.IsEmpty()) {
return NS_OK; return NS_OK;
} }

View File

@ -1,37 +1,51 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public /* 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 * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsPermission.h" #include "nsPermission.h"
#include "nsContentUtils.h"
#include "nsIClassInfoImpl.h" #include "nsIClassInfoImpl.h"
#include "nsIEffectiveTLDService.h"
#include "mozilla/BasePrincipal.h"
// nsPermission Implementation // nsPermission Implementation
NS_IMPL_CLASSINFO(nsPermission, nullptr, 0, {0}) NS_IMPL_CLASSINFO(nsPermission, nullptr, 0, {0})
NS_IMPL_ISUPPORTS_CI(nsPermission, nsIPermission) NS_IMPL_ISUPPORTS_CI(nsPermission, nsIPermission)
nsPermission::nsPermission(nsIPrincipal* aPrincipal, nsPermission::nsPermission(const nsACString &aHost,
uint32_t aAppId,
bool aIsInBrowserElement,
const nsACString &aType, const nsACString &aType,
uint32_t aCapability, uint32_t aCapability,
uint32_t aExpireType, uint32_t aExpireType,
int64_t aExpireTime) int64_t aExpireTime)
: mPrincipal(aPrincipal) : mHost(aHost)
, mType(aType) , mType(aType)
, mCapability(aCapability) , mCapability(aCapability)
, mExpireType(aExpireType) , mExpireType(aExpireType)
, mExpireTime(aExpireTime) , mExpireTime(aExpireTime)
, mAppId(aAppId)
, mIsInBrowserElement(aIsInBrowserElement)
{ {
} }
NS_IMETHODIMP NS_IMETHODIMP
nsPermission::GetPrincipal(nsIPrincipal** aPrincipal) nsPermission::GetHost(nsACString &aHost)
{ {
nsCOMPtr<nsIPrincipal> copy = mPrincipal; aHost = mHost;
copy.forget(aPrincipal); return NS_OK;
}
NS_IMETHODIMP
nsPermission::GetAppId(uint32_t* aAppId)
{
*aAppId = mAppId;
return NS_OK;
}
NS_IMETHODIMP
nsPermission::GetIsInBrowserElement(bool* aIsInBrowserElement)
{
*aIsInBrowserElement = mIsInBrowserElement;
return NS_OK; return NS_OK;
} }
@ -62,117 +76,3 @@ nsPermission::GetExpireTime(int64_t *aExpireTime)
*aExpireTime = mExpireTime; *aExpireTime = mExpireTime;
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsPermission::Matches(nsIPrincipal* aPrincipal, bool aExactHost, bool* aMatches)
{
NS_ENSURE_ARG_POINTER(aPrincipal);
NS_ENSURE_ARG_POINTER(aMatches);
*aMatches = false;
// If the principals are equal, then they match.
if (mPrincipal->Equals(aPrincipal)) {
*aMatches = true;
return NS_OK;
}
// If we are matching with an exact host, we're done now - the permissions don't match
// otherwise, we need to start comparing subdomains!
if (aExactHost) {
return NS_OK;
}
// Compare their OriginAttributes
const mozilla::OriginAttributes& theirAttrs = mozilla::BasePrincipal::Cast(aPrincipal)->OriginAttributesRef();
const mozilla::OriginAttributes& ourAttrs = mozilla::BasePrincipal::Cast(mPrincipal)->OriginAttributesRef();
if (theirAttrs != ourAttrs) {
return NS_OK;
}
nsCOMPtr<nsIURI> theirURI;
nsresult rv = aPrincipal->GetURI(getter_AddRefs(theirURI));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIURI> ourURI;
rv = mPrincipal->GetURI(getter_AddRefs(ourURI));
NS_ENSURE_SUCCESS(rv, rv);
// Compare schemes
nsAutoCString theirScheme;
rv = theirURI->GetScheme(theirScheme);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString ourScheme;
rv = ourURI->GetScheme(ourScheme);
NS_ENSURE_SUCCESS(rv, rv);
if (theirScheme != ourScheme) {
return NS_OK;
}
// Compare ports
int32_t theirPort;
rv = theirURI->GetPort(&theirPort);
NS_ENSURE_SUCCESS(rv, rv);
int32_t ourPort;
rv = ourURI->GetPort(&ourPort);
NS_ENSURE_SUCCESS(rv, rv);
if (theirPort != ourPort) {
return NS_OK;
}
// Check if the host or any subdomain of their host matches.
nsAutoCString theirHost;
rv = theirURI->GetHost(theirHost);
if (NS_FAILED(rv) || theirHost.IsEmpty()) {
return NS_OK;
}
nsAutoCString ourHost;
rv = ourURI->GetHost(ourHost);
if (NS_FAILED(rv) || ourHost.IsEmpty()) {
return NS_OK;
}
nsCOMPtr<nsIEffectiveTLDService> tldService =
do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
if (!tldService) {
NS_ERROR("Should have a tld service!");
return NS_ERROR_FAILURE;
}
// This loop will not loop forever, as GetNextSubDomain will eventually fail
// with NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS.
while (theirHost != ourHost) {
rv = tldService->GetNextSubDomain(theirHost, theirHost);
if (NS_FAILED(rv)) {
if (rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
return NS_OK;
} else {
return rv;
}
}
}
*aMatches = true;
return NS_OK;
}
NS_IMETHODIMP
nsPermission::MatchesURI(nsIURI* aURI, bool aExactHost, bool* aMatches)
{
NS_ENSURE_ARG_POINTER(aURI);
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
NS_ENSURE_TRUE(secMan, NS_ERROR_FAILURE);
nsCOMPtr<nsIPrincipal> principal;
nsresult rv = secMan->GetNoAppCodebasePrincipal(aURI, getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, rv);
return Matches(principal, aExactHost, aMatches);
}

View File

@ -18,7 +18,9 @@ public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_DECL_NSIPERMISSION NS_DECL_NSIPERMISSION
nsPermission(nsIPrincipal* aPrincipal, nsPermission(const nsACString &aHost,
uint32_t aAppId,
bool aIsInBrowserElement,
const nsACString &aType, const nsACString &aType,
uint32_t aCapability, uint32_t aCapability,
uint32_t aExpireType, uint32_t aExpireType,
@ -27,11 +29,13 @@ public:
protected: protected:
virtual ~nsPermission() {}; virtual ~nsPermission() {};
nsCOMPtr<nsIPrincipal> mPrincipal; nsCString mHost;
nsCString mType; nsCString mType;
uint32_t mCapability; uint32_t mCapability;
uint32_t mExpireType; uint32_t mExpireType;
int64_t mExpireTime; int64_t mExpireTime;
uint32_t mAppId;
bool mIsInBrowserElement;
}; };
#endif // nsPermission_h__ #endif // nsPermission_h__

File diff suppressed because it is too large Load Diff

View File

@ -71,22 +71,35 @@ public:
{ {
public: public:
explicit PermissionKey(nsIPrincipal* aPrincipal); explicit PermissionKey(nsIPrincipal* aPrincipal);
explicit PermissionKey(const nsACString& aOrigin) PermissionKey(const nsACString& aHost,
: mOrigin(aOrigin) uint32_t aAppId,
bool aIsInBrowserElement)
: mHost(aHost)
, mAppId(aAppId)
, mIsInBrowserElement(aIsInBrowserElement)
{ {
} }
bool operator==(const PermissionKey& aKey) const { bool operator==(const PermissionKey& aKey) const {
return mOrigin.Equals(aKey.mOrigin); return mHost.Equals(aKey.mHost) &&
mAppId == aKey.mAppId &&
mIsInBrowserElement == aKey.mIsInBrowserElement;
} }
PLDHashNumber GetHashCode() const { PLDHashNumber GetHashCode() const {
return mozilla::HashString(mOrigin); nsAutoCString str;
str.Assign(mHost);
str.AppendInt(mAppId);
str.AppendInt(static_cast<int32_t>(mIsInBrowserElement));
return mozilla::HashString(str);
} }
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PermissionKey) NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PermissionKey)
nsCString mOrigin; nsCString mHost;
uint32_t mAppId;
bool mIsInBrowserElement;
private: private:
// Default ctor shouldn't be used. // Default ctor shouldn't be used.
@ -209,9 +222,11 @@ private:
int32_t GetTypeIndex(const char *aTypeString, int32_t GetTypeIndex(const char *aTypeString,
bool aAdd); bool aAdd);
PermissionHashKey* GetPermissionHashKey(nsIPrincipal* aPrincipal, PermissionHashKey* GetPermissionHashKey(const nsACString& aHost,
uint32_t aType, uint32_t aAppId,
bool aExactHostMatch); bool aIsInBrowserElement,
uint32_t aType,
bool aExactHostMatch);
nsresult CommonTestPermission(nsIPrincipal* aPrincipal, nsresult CommonTestPermission(nsIPrincipal* aPrincipal,
const char *aType, const char *aType,
@ -226,7 +241,9 @@ private:
nsresult ImportDefaults(); nsresult ImportDefaults();
nsresult _DoImport(nsIInputStream *inputStream, mozIStorageConnection *aConn); nsresult _DoImport(nsIInputStream *inputStream, mozIStorageConnection *aConn);
nsresult Read(); nsresult Read();
void NotifyObserversWithPermission(nsIPrincipal* aPrincipal, void NotifyObserversWithPermission(const nsACString &aHost,
uint32_t aAppId,
bool aIsInBrowserElement,
const nsCString &aType, const nsCString &aType,
uint32_t aPermission, uint32_t aPermission,
uint32_t aExpireType, uint32_t aExpireType,
@ -244,12 +261,14 @@ private:
static void UpdateDB(OperationType aOp, static void UpdateDB(OperationType aOp,
mozIStorageAsyncStatement* aStmt, mozIStorageAsyncStatement* aStmt,
int64_t aID, int64_t aID,
const nsACString& aOrigin, const nsACString& aHost,
const nsACString& aType, const nsACString& aType,
uint32_t aPermission, uint32_t aPermission,
uint32_t aExpireType, uint32_t aExpireType,
int64_t aExpireTime, int64_t aExpireTime,
int64_t aModificationTime); int64_t aModificationTime,
uint32_t aAppId,
bool aIsInBrowserElement);
nsresult RemoveExpiredPermissionsForApp(uint32_t aAppId); nsresult RemoveExpiredPermissionsForApp(uint32_t aAppId);

View File

@ -42,7 +42,7 @@ function getPermissionCountForApp(aAppId) {
while (enumerator.hasMoreElements()) { while (enumerator.hasMoreElements()) {
var permission = enumerator.getNext().QueryInterface(Ci.nsIPermission); var permission = enumerator.getNext().QueryInterface(Ci.nsIPermission);
if (permission.principal.appId == aAppId || aAppId == -1) { if (permission.appId == aAppId || aAppId == -1) {
nbPermissions++; nbPermissions++;
} }
} }

View File

@ -2,10 +2,8 @@
http://creativecommons.org/publicdomain/zero/1.0/ */ http://creativecommons.org/publicdomain/zero/1.0/ */
// The origin we use in most of the tests. // The origin we use in most of the tests.
const TEST_ORIGIN = NetUtil.newURI("http://example.org"); const TEST_ORIGIN = "example.org";
const TEST_ORIGIN_HTTPS = NetUtil.newURI("https://example.org"); const TEST_ORIGIN_2 = "example.com";
const TEST_ORIGIN_2 = NetUtil.newURI("http://example.com");
const TEST_ORIGIN_3 = NetUtil.newURI("https://example2.com:8080");
const TEST_PERMISSION = "test-permission"; const TEST_PERMISSION = "test-permission";
Components.utils.import("resource://gre/modules/Promise.jsm"); Components.utils.import("resource://gre/modules/Promise.jsm");
@ -37,10 +35,8 @@ add_task(function* do_test() {
conv.writeString("# this is a comment\n"); conv.writeString("# this is a comment\n");
conv.writeString("\n"); // a blank line! conv.writeString("\n"); // a blank line!
conv.writeString("host\t" + TEST_PERMISSION + "\t1\t" + TEST_ORIGIN.host + "\n"); conv.writeString("host\t" + TEST_PERMISSION + "\t1\t" + TEST_ORIGIN + "\n");
conv.writeString("host\t" + TEST_PERMISSION + "\t1\t" + TEST_ORIGIN_2.host + "\n"); conv.writeString("host\t" + TEST_PERMISSION + "\t1\t" + TEST_ORIGIN_2 + "\n");
conv.writeString("origin\t" + TEST_PERMISSION + "\t1\t" + TEST_ORIGIN_3.spec + "\n");
conv.writeString("origin\t" + TEST_PERMISSION + "\t1\t" + TEST_ORIGIN.spec + "^appId=1000&inBrowser=1\n");
ostream.close(); ostream.close();
// Set the preference used by the permission manager so the file is read. // Set the preference used by the permission manager so the file is read.
@ -51,30 +47,14 @@ add_task(function* do_test() {
getService(Ci.nsIPermissionManager); getService(Ci.nsIPermissionManager);
// test the default permission was applied. // test the default permission was applied.
let principal = Services.scriptSecurityManager.getNoAppCodebasePrincipal(TEST_ORIGIN); let permURI = NetUtil.newURI("http://" + TEST_ORIGIN);
let principalHttps = Services.scriptSecurityManager.getNoAppCodebasePrincipal(TEST_ORIGIN_HTTPS); let principal = Services.scriptSecurityManager.getNoAppCodebasePrincipal(permURI);
let principal2 = Services.scriptSecurityManager.getNoAppCodebasePrincipal(TEST_ORIGIN_2);
let principal3 = Services.scriptSecurityManager.getNoAppCodebasePrincipal(TEST_ORIGIN_3);
let principal4 = Services.scriptSecurityManager.getAppCodebasePrincipal(TEST_ORIGIN, 1000, true);
let principal5 = Services.scriptSecurityManager.getAppCodebasePrincipal(TEST_ORIGIN_3, 1000, true);
do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION, do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION,
pm.testPermissionFromPrincipal(principal, TEST_PERMISSION)); pm.testPermissionFromPrincipal(principal, TEST_PERMISSION));
do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION,
pm.testPermissionFromPrincipal(principalHttps, TEST_PERMISSION));
do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION,
pm.testPermissionFromPrincipal(principal3, TEST_PERMISSION));
do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION,
pm.testPermissionFromPrincipal(principal4, TEST_PERMISSION));
// Didn't add
do_check_eq(Ci.nsIPermissionManager.UNKNOWN_ACTION,
pm.testPermissionFromPrincipal(principal5, TEST_PERMISSION));
// the permission should exist in the enumerator. // the permission should exist in the enumerator.
do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION, findCapabilityViaEnum(TEST_ORIGIN)); do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION, findCapabilityViaEnum());
do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION, findCapabilityViaEnum(TEST_ORIGIN_3));
// but should not have been written to the DB // but should not have been written to the DB
yield checkCapabilityViaDB(null); yield checkCapabilityViaDB(null);
@ -83,10 +63,6 @@ add_task(function* do_test() {
do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION, do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION,
pm.testPermissionFromPrincipal(principal, TEST_PERMISSION)); pm.testPermissionFromPrincipal(principal, TEST_PERMISSION));
do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION,
pm.testPermissionFromPrincipal(principal3, TEST_PERMISSION));
do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION,
pm.testPermissionFromPrincipal(principal4, TEST_PERMISSION));
// Asking for this permission to be removed should result in that permission // Asking for this permission to be removed should result in that permission
// having UNKNOWN_ACTION // having UNKNOWN_ACTION
@ -129,6 +105,9 @@ add_task(function* do_test() {
// check default permissions and removeAllSince work as expected. // check default permissions and removeAllSince work as expected.
pm.removeAll(); // ensure only defaults are there. pm.removeAll(); // ensure only defaults are there.
let permURI2 = NetUtil.newURI("http://" + TEST_ORIGIN_2);
let principal2 = Services.scriptSecurityManager.getNoAppCodebasePrincipal(permURI2);
// default for both principals is allow. // default for both principals is allow.
do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION, do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION,
pm.testPermissionFromPrincipal(principal, TEST_PERMISSION)); pm.testPermissionFromPrincipal(principal, TEST_PERMISSION));
@ -170,12 +149,12 @@ add_task(function* do_test() {
// use an enumerator to find the requested permission. Returns the permission // use an enumerator to find the requested permission. Returns the permission
// value (ie, the "capability" in nsIPermission parlance) or null if it can't // value (ie, the "capability" in nsIPermission parlance) or null if it can't
// be found. // be found.
function findCapabilityViaEnum(origin = TEST_ORIGIN, type = TEST_PERMISSION) { function findCapabilityViaEnum(host = TEST_ORIGIN, type = TEST_PERMISSION) {
let result = undefined; let result = undefined;
let e = Services.perms.enumerator; let e = Services.perms.enumerator;
while (e.hasMoreElements()) { while (e.hasMoreElements()) {
let perm = e.getNext().QueryInterface(Ci.nsIPermission); let perm = e.getNext().QueryInterface(Ci.nsIPermission);
if (perm.matchesURI(origin, true) && if (perm.host == host &&
perm.type == type) { perm.type == type) {
if (result !== undefined) { if (result !== undefined) {
// we've already found one previously - that's bad! // we've already found one previously - that's bad!
@ -192,12 +171,12 @@ function findCapabilityViaEnum(origin = TEST_ORIGIN, type = TEST_PERMISSION) {
// distinct possibility exists that our checking of the DB will happen before // distinct possibility exists that our checking of the DB will happen before
// the permission manager update has completed - so we just retry a few times. // the permission manager update has completed - so we just retry a few times.
// Returns a promise. // Returns a promise.
function checkCapabilityViaDB(expected, origin = TEST_ORIGIN, type = TEST_PERMISSION) { function checkCapabilityViaDB(expected, host = TEST_ORIGIN, type = TEST_PERMISSION) {
let deferred = Promise.defer(); let deferred = Promise.defer();
let count = 0; let count = 0;
let max = 20; let max = 20;
let do_check = () => { let do_check = () => {
let got = findCapabilityViaDB(origin, type); let got = findCapabilityViaDB(host, type);
if (got == expected) { if (got == expected) {
// the do_check_eq() below will succeed - which is what we want. // the do_check_eq() below will succeed - which is what we want.
do_check_eq(got, expected, "The database has the expected value"); do_check_eq(got, expected, "The database has the expected value");
@ -221,10 +200,7 @@ function checkCapabilityViaDB(expected, origin = TEST_ORIGIN, type = TEST_PERMIS
// use the DB to find the requested permission. Returns the permission // use the DB to find the requested permission. Returns the permission
// value (ie, the "capability" in nsIPermission parlance) or null if it can't // value (ie, the "capability" in nsIPermission parlance) or null if it can't
// be found. // be found.
function findCapabilityViaDB(origin = TEST_ORIGIN, type = TEST_PERMISSION) { function findCapabilityViaDB(host = TEST_ORIGIN, type = TEST_PERMISSION) {
let principal = Services.scriptSecurityManager.getNoAppCodebasePrincipal(origin);
let originStr = principal.origin;
let file = Services.dirsvc.get("ProfD", Ci.nsIFile); let file = Services.dirsvc.get("ProfD", Ci.nsIFile);
file.append("permissions.sqlite"); file.append("permissions.sqlite");
@ -234,8 +210,8 @@ function findCapabilityViaDB(origin = TEST_ORIGIN, type = TEST_PERMISSION) {
let connection = storage.openDatabase(file); let connection = storage.openDatabase(file);
let query = connection.createStatement( let query = connection.createStatement(
"SELECT permission FROM moz_hosts WHERE origin = :origin AND type = :type"); "SELECT permission FROM moz_hosts WHERE host = :host AND type = :type");
query.bindByName("origin", originStr); query.bindByName("host", host);
query.bindByName("type", type); query.bindByName("type", type);
if (!query.executeStep()) { if (!query.executeStep()) {

View File

@ -29,20 +29,20 @@ function run_test() {
pm.addFromPrincipal(principal, "test/pobject", pm.ALLOW_ACTION); pm.addFromPrincipal(principal, "test/pobject", pm.ALLOW_ACTION);
var rootPerm = pm.getPermissionObject(principal, "test/pobject", false); var rootPerm = pm.getPermissionObject(principal, "test/pobject", false);
do_check_true(rootPerm != null); do_check_true(rootPerm != null);
do_check_eq(rootPerm.principal.origin, "http://example.com"); do_check_eq(rootPerm.host, "example.com");
do_check_eq(rootPerm.type, "test/pobject"); do_check_eq(rootPerm.type, "test/pobject");
do_check_eq(rootPerm.capability, pm.ALLOW_ACTION); do_check_eq(rootPerm.capability, pm.ALLOW_ACTION);
do_check_eq(rootPerm.expireType, pm.EXPIRE_NEVER); do_check_eq(rootPerm.expireType, pm.EXPIRE_NEVER);
var rootPerm2 = pm.getPermissionObject(principal, "test/pobject", true); var rootPerm2 = pm.getPermissionObject(principal, "test/pobject", true);
do_check_true(rootPerm != null); do_check_true(rootPerm != null);
do_check_eq(rootPerm.principal.origin, "http://example.com"); do_check_eq(rootPerm.host, "example.com");
var subPerm = pm.getPermissionObject(subPrincipal, "test/pobject", true); var subPerm = pm.getPermissionObject(subPrincipal, "test/pobject", true);
do_check_null(subPerm); do_check_null(subPerm);
subPerm = pm.getPermissionObject(subPrincipal, "test/pobject", false); subPerm = pm.getPermissionObject(subPrincipal, "test/pobject", false);
do_check_true(subPerm != null); do_check_true(subPerm != null);
do_check_eq(subPerm.principal.origin, "http://example.com"); do_check_eq(subPerm.host, "example.com");
do_check_eq(subPerm.type, "test/pobject"); do_check_eq(subPerm.type, "test/pobject");
do_check_eq(subPerm.capability, pm.ALLOW_ACTION); do_check_eq(subPerm.capability, pm.ALLOW_ACTION);
@ -50,7 +50,7 @@ function run_test() {
do_check_null(subPerm); do_check_null(subPerm);
subPerm = pm.getPermissionObject(subSubPrincipal, "test/pobject", false); subPerm = pm.getPermissionObject(subSubPrincipal, "test/pobject", false);
do_check_true(subPerm != null); do_check_true(subPerm != null);
do_check_eq(subPerm.principal.origin, "http://example.com"); do_check_eq(subPerm.host, "example.com");
pm.addFromPrincipal(principal, "test/pobject", pm.DENY_ACTION, pm.EXPIRE_SESSION); pm.addFromPrincipal(principal, "test/pobject", pm.DENY_ACTION, pm.EXPIRE_SESSION);
@ -63,28 +63,28 @@ function run_test() {
do_check_eq(rootPerm.expireType, pm.EXPIRE_SESSION); do_check_eq(rootPerm.expireType, pm.EXPIRE_SESSION);
subPerm = pm.getPermissionObject(subPrincipal, "test/pobject", false); subPerm = pm.getPermissionObject(subPrincipal, "test/pobject", false);
do_check_eq(subPerm.principal.origin, "http://example.com"); do_check_eq(subPerm.host, "example.com");
do_check_eq(subPerm.capability, pm.DENY_ACTION); do_check_eq(subPerm.capability, pm.DENY_ACTION);
do_check_eq(subPerm.expireType, pm.EXPIRE_SESSION); do_check_eq(subPerm.expireType, pm.EXPIRE_SESSION);
pm.addFromPrincipal(subPrincipal, "test/pobject", pm.PROMPT_ACTION); pm.addFromPrincipal(subPrincipal, "test/pobject", pm.PROMPT_ACTION);
rootPerm = pm.getPermissionObject(principal, "test/pobject", true); rootPerm = pm.getPermissionObject(principal, "test/pobject", true);
do_check_eq(rootPerm.principal.origin, "http://example.com"); do_check_eq(rootPerm.host, "example.com");
do_check_eq(rootPerm.capability, pm.DENY_ACTION); do_check_eq(rootPerm.capability, pm.DENY_ACTION);
subPerm = pm.getPermissionObject(subPrincipal, "test/pobject", true); subPerm = pm.getPermissionObject(subPrincipal, "test/pobject", true);
do_check_eq(subPerm.principal.origin, "http://sub.example.com"); do_check_eq(subPerm.host, "sub.example.com");
do_check_eq(subPerm.capability, pm.PROMPT_ACTION); do_check_eq(subPerm.capability, pm.PROMPT_ACTION);
subPerm = pm.getPermissionObject(subPrincipal, "test/pobject", false); subPerm = pm.getPermissionObject(subPrincipal, "test/pobject", false);
do_check_eq(subPerm.principal.origin, "http://sub.example.com"); do_check_eq(subPerm.host, "sub.example.com");
do_check_eq(subPerm.capability, pm.PROMPT_ACTION); do_check_eq(subPerm.capability, pm.PROMPT_ACTION);
subPerm = pm.getPermissionObject(subSubPrincipal, "test/pobject", true); subPerm = pm.getPermissionObject(subSubPrincipal, "test/pobject", true);
do_check_null(subPerm); do_check_null(subPerm);
subPerm = pm.getPermissionObject(subSubPrincipal, "test/pobject", false); subPerm = pm.getPermissionObject(subSubPrincipal, "test/pobject", false);
do_check_eq(subPerm.principal.origin, "http://sub.example.com"); do_check_eq(subPerm.host, "sub.example.com");
do_check_eq(subPerm.capability, pm.PROMPT_ACTION); do_check_eq(subPerm.capability, pm.PROMPT_ACTION);
pm.removeFromPrincipal(principal, "test/pobject"); pm.removeFromPrincipal(principal, "test/pobject");

View File

@ -121,7 +121,7 @@ function run_test() {
// The schema should be upgraded to 4, and a 'modificationTime' column should // The schema should be upgraded to 4, and a 'modificationTime' column should
// exist with all records having a value of 0. // exist with all records having a value of 0.
do_check_eq(connection.schemaVersion, 5); do_check_eq(connection.schemaVersion, 4);
let select = connection.createStatement("SELECT modificationTime FROM moz_hosts") let select = connection.createStatement("SELECT modificationTime FROM moz_hosts")
let numMigrated = 0; let numMigrated = 0;

View File

@ -39,4 +39,10 @@ function run_test() {
do_check_eq(pm.testPermissionFromPrincipal(principal, "test/local-files"), pm.UNKNOWN_ACTION); do_check_eq(pm.testPermissionFromPrincipal(principal, "test/local-files"), pm.UNKNOWN_ACTION);
do_check_eq(pm.testPermissionFromPrincipal(witnessPrincipal, "test/local-files"), pm.UNKNOWN_ACTION); do_check_eq(pm.testPermissionFromPrincipal(witnessPrincipal, "test/local-files"), pm.UNKNOWN_ACTION);
do_check_eq(pm.testPermissionFromPrincipal(fileInDirPrincipal, "test/local-files"), pm.UNKNOWN_ACTION); do_check_eq(pm.testPermissionFromPrincipal(fileInDirPrincipal, "test/local-files"), pm.UNKNOWN_ACTION);
}
// Add the magic "<file>" permission and make sure all "file://" now have the permission.
pm.addFromPrincipal(getPrincipalFromURIString("http://<file>"), "test/local-files", pm.ALLOW_ACTION, 0, 0);
do_check_eq(pm.testPermissionFromPrincipal(principal, "test/local-files"), pm.ALLOW_ACTION);
do_check_eq(pm.testPermissionFromPrincipal(witnessPrincipal, "test/local-files"), pm.ALLOW_ACTION);
do_check_eq(pm.testPermissionFromPrincipal(fileInDirPrincipal, "test/local-files"), pm.ALLOW_ACTION);
}

View File

@ -0,0 +1,41 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function run_test() {
// initialize the permission manager service
const kTestAddr = "test@example.org";
const kType = "test-mailto";
const kCapability = 1;
// make a mailto: URI with parameters
let uri = Services.io.newURI("mailto:" + kTestAddr + "?subject=test", null,
null);
// add a permission entry for that URI
Services.perms.add(uri, kType, kCapability);
do_check_true(permission_exists(kTestAddr, kType, kCapability));
// remove the permission, and make sure it was removed
Services.perms.remove(uri, kType);
do_check_false(permission_exists(kTestAddr, kType, kCapability));
uri = Services.io.newURI("mailto:" + kTestAddr, null, null);
Services.perms.add(uri, kType, kCapability);
do_check_true(permission_exists(kTestAddr, kType, kCapability));
Services.perms.remove(uri, kType);
do_check_false(permission_exists(kTestAddr, kType, kCapability));
}
function permission_exists(aHost, aType, aCapability) {
let e = Services.perms.enumerator;
while (e.hasMoreElements()) {
let perm = e.getNext().QueryInterface(Ci.nsIPermission);
if (perm.host == aHost &&
perm.type == aType &&
perm.capability == aCapability) {
return true;
}
}
return false;
}

View File

@ -1,129 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function matches_always(perm, principals) {
principals.forEach((principal) => {
do_check_true(perm.matches(principal, true), "perm: " + perm.principal.origin + ", princ: " + principal.origin);
do_check_true(perm.matches(principal, false), "perm: " + perm.principal.origin + ", princ: " + principal.origin);
});
}
function matches_weak(perm, principals) {
principals.forEach((principal) => {
do_check_false(perm.matches(principal, true), "perm: " + perm.principal.origin + ", princ: " + principal.origin);
do_check_true(perm.matches(principal, false), "perm: " + perm.principal.origin + ", princ: " + principal.origin);
});
}
function matches_never(perm, principals) {
principals.forEach((principal) => {
do_check_false(perm.matches(principal, true), "perm: " + perm.principal.origin + ", princ: " + principal.origin);
do_check_false(perm.matches(principal, false), "perm: " + perm.principal.origin + ", princ: " + principal.origin);
});
}
function run_test() {
// initialize the permission manager service
let pm = Cc["@mozilla.org/permissionmanager;1"].
getService(Ci.nsIPermissionManager);
let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(Ci.nsIScriptSecurityManager);
// Add some permissions
let uri0 = NetUtil.newURI("http://google.com/search?q=foo#hashtag", null, null);
let uri1 = NetUtil.newURI("http://hangouts.google.com/subdir", null, null);
let uri2 = NetUtil.newURI("http://google.org/", null, null);
let uri3 = NetUtil.newURI("https://google.com/some/random/subdirectory", null, null);
let uri4 = NetUtil.newURI("https://hangouts.google.com/#!/hangout", null, null);
let uri5 = NetUtil.newURI("http://google.com:8096/", null, null);
let uri0_n_n = secMan.getNoAppCodebasePrincipal(uri0);
let uri1_n_n = secMan.getNoAppCodebasePrincipal(uri1);
let uri2_n_n = secMan.getNoAppCodebasePrincipal(uri2);
let uri3_n_n = secMan.getNoAppCodebasePrincipal(uri3);
let uri4_n_n = secMan.getNoAppCodebasePrincipal(uri4);
let uri5_n_n = secMan.getNoAppCodebasePrincipal(uri5);
let uri0_1000_n = secMan.getAppCodebasePrincipal(uri0, 1000, false);
let uri1_1000_n = secMan.getAppCodebasePrincipal(uri1, 1000, false);
let uri2_1000_n = secMan.getAppCodebasePrincipal(uri2, 1000, false);
let uri3_1000_n = secMan.getAppCodebasePrincipal(uri3, 1000, false);
let uri4_1000_n = secMan.getAppCodebasePrincipal(uri4, 1000, false);
let uri5_1000_n = secMan.getAppCodebasePrincipal(uri5, 1000, false);
let uri0_1000_y = secMan.getAppCodebasePrincipal(uri0, 1000, true);
let uri1_1000_y = secMan.getAppCodebasePrincipal(uri1, 1000, true);
let uri2_1000_y = secMan.getAppCodebasePrincipal(uri2, 1000, true);
let uri3_1000_y = secMan.getAppCodebasePrincipal(uri3, 1000, true);
let uri4_1000_y = secMan.getAppCodebasePrincipal(uri4, 1000, true);
let uri5_1000_y = secMan.getAppCodebasePrincipal(uri5, 1000, true);
let uri0_2000_n = secMan.getAppCodebasePrincipal(uri0, 2000, false);
let uri1_2000_n = secMan.getAppCodebasePrincipal(uri1, 2000, false);
let uri2_2000_n = secMan.getAppCodebasePrincipal(uri2, 2000, false);
let uri3_2000_n = secMan.getAppCodebasePrincipal(uri3, 2000, false);
let uri4_2000_n = secMan.getAppCodebasePrincipal(uri4, 2000, false);
let uri5_2000_n = secMan.getAppCodebasePrincipal(uri5, 2000, false);
let uri0_2000_y = secMan.getAppCodebasePrincipal(uri0, 2000, true);
let uri1_2000_y = secMan.getAppCodebasePrincipal(uri1, 2000, true);
let uri2_2000_y = secMan.getAppCodebasePrincipal(uri2, 2000, true);
let uri3_2000_y = secMan.getAppCodebasePrincipal(uri3, 2000, true);
let uri4_2000_y = secMan.getAppCodebasePrincipal(uri4, 2000, true);
let uri5_2000_y = secMan.getAppCodebasePrincipal(uri5, 2000, true);
pm.addFromPrincipal(uri0_n_n, "test/matches", pm.ALLOW_ACTION);
let perm_n_n = pm.getPermissionObject(uri0_n_n, "test/matches", true);
pm.addFromPrincipal(uri0_1000_n, "test/matches", pm.ALLOW_ACTION);
let perm_1000_n = pm.getPermissionObject(uri0_1000_n, "test/matches", true);
pm.addFromPrincipal(uri0_1000_y, "test/matches", pm.ALLOW_ACTION);
let perm_1000_y = pm.getPermissionObject(uri0_1000_y, "test/matches", true);
pm.addFromPrincipal(uri0_2000_n, "test/matches", pm.ALLOW_ACTION);
let perm_2000_n = pm.getPermissionObject(uri0_2000_n, "test/matches", true);
pm.addFromPrincipal(uri0_2000_y, "test/matches", pm.ALLOW_ACTION);
let perm_2000_y = pm.getPermissionObject(uri0_2000_y, "test/matches", true);
matches_always(perm_n_n, [uri0_n_n]);
matches_weak(perm_n_n, [uri1_n_n]);
matches_never(perm_n_n, [uri2_n_n, uri3_n_n, uri4_n_n, uri5_n_n,
uri0_1000_n, uri1_1000_n, uri2_1000_n, uri3_1000_n, uri4_1000_n, uri5_1000_n,
uri0_1000_y, uri1_1000_y, uri2_1000_y, uri3_1000_y, uri4_1000_y, uri5_1000_y,
uri0_2000_n, uri1_2000_n, uri2_2000_n, uri3_2000_n, uri4_2000_n, uri5_2000_n,
uri0_2000_y, uri1_2000_y, uri2_2000_y, uri3_2000_y, uri4_2000_y, uri5_2000_y]);
matches_always(perm_1000_n, [uri0_1000_n]);
matches_weak(perm_1000_n, [uri1_1000_n]);
matches_never(perm_1000_n, [uri2_1000_n, uri3_1000_n, uri4_1000_n, uri5_1000_n,
uri0_n_n, uri1_n_n, uri2_n_n, uri3_n_n, uri4_n_n, uri5_n_n,
uri0_1000_y, uri1_1000_y, uri2_1000_y, uri3_1000_y, uri4_1000_y, uri5_1000_y,
uri0_2000_n, uri1_2000_n, uri2_2000_n, uri3_2000_n, uri4_2000_n, uri5_2000_n,
uri0_2000_y, uri1_2000_y, uri2_2000_y, uri3_2000_y, uri4_2000_y, uri5_2000_y]);
matches_always(perm_1000_y, [uri0_1000_y]);
matches_weak(perm_1000_y, [uri1_1000_y]);
matches_never(perm_1000_y, [uri2_1000_y, uri3_1000_y, uri4_1000_y, uri5_1000_y,
uri0_n_n, uri1_n_n, uri2_n_n, uri3_n_n, uri4_n_n, uri5_n_n,
uri0_1000_n, uri1_1000_n, uri2_1000_n, uri3_1000_n, uri4_1000_n, uri5_1000_n,
uri0_2000_n, uri1_2000_n, uri2_2000_n, uri3_2000_n, uri4_2000_n, uri5_2000_n,
uri0_2000_y, uri1_2000_y, uri2_2000_y, uri3_2000_y, uri4_2000_y, uri5_2000_y]);
matches_always(perm_2000_n, [uri0_2000_n]);
matches_weak(perm_2000_n, [uri1_2000_n]);
matches_never(perm_2000_n, [uri2_2000_n, uri3_2000_n, uri4_2000_n, uri5_2000_n,
uri0_n_n, uri1_n_n, uri2_n_n, uri3_n_n, uri4_n_n, uri5_n_n,
uri0_2000_y, uri1_2000_y, uri2_2000_y, uri3_2000_y, uri4_2000_y, uri5_2000_y,
uri0_1000_n, uri1_1000_n, uri2_1000_n, uri3_1000_n, uri4_1000_n, uri5_1000_n,
uri0_1000_y, uri1_1000_y, uri2_1000_y, uri3_1000_y, uri4_1000_y, uri5_1000_y]);
matches_always(perm_2000_y, [uri0_2000_y]);
matches_weak(perm_2000_y, [uri1_2000_y]);
matches_never(perm_2000_y, [uri2_2000_y, uri3_2000_y, uri4_2000_y, uri5_2000_y,
uri0_n_n, uri1_n_n, uri2_n_n, uri3_n_n, uri4_n_n, uri5_n_n,
uri0_2000_n, uri1_2000_n, uri2_2000_n, uri3_2000_n, uri4_2000_n, uri5_2000_n,
uri0_1000_n, uri1_1000_n, uri2_1000_n, uri3_1000_n, uri4_1000_n, uri5_1000_n,
uri0_1000_y, uri1_1000_y, uri2_1000_y, uri3_1000_y, uri4_1000_y, uri5_1000_y]);
// Clean up!
pm.removeAll();
}

View File

@ -1,150 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function matches_always(perm, uris) {
uris.forEach((uri) => {
do_check_true(perm.matchesURI(uri, true), "perm: " + perm.principal.origin + ", URI: " + uri.spec);
do_check_true(perm.matchesURI(uri, false), "perm: " + perm.principal.origin + ", URI: " + uri.spec);
});
}
function matches_weak(perm, uris) {
uris.forEach((uri) => {
do_check_false(perm.matchesURI(uri, true), "perm: " + perm.principal.origin + ", URI: " + uri.spec);
do_check_true(perm.matchesURI(uri, false), "perm: " + perm.principal.origin + ", URI: " + uri.spec);
});
}
function matches_never(perm, uris) {
uris.forEach((uri) => {
do_check_false(perm.matchesURI(uri, true), "perm: " + perm.principal.origin + ", URI: " + uri.spec);
do_check_false(perm.matchesURI(uri, false), "perm: " + perm.principal.origin + ", URI: " + uri.spec);
});
}
function mk_permission(uri, isAppPermission = false) {
let pm = Cc["@mozilla.org/permissionmanager;1"].
getService(Ci.nsIPermissionManager);
let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(Ci.nsIScriptSecurityManager);
// Get the permission from the principal!
let principal = isAppPermission ?
secMan.getAppCodebasePrincipal(uri, 1000, false) :
secMan.getNoAppCodebasePrincipal(uri);
pm.addFromPrincipal(principal, "test/matchesuri", pm.ALLOW_ACTION);
let permission = pm.getPermissionObject(principal, "test/matchesuri", true);
return permission;
}
function run_test() {
// initialize the permission manager service
let pm = Cc["@mozilla.org/permissionmanager;1"].
getService(Ci.nsIPermissionManager);
let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(Ci.nsIScriptSecurityManager);
let fileprefix = "file:///";
if (Services.appinfo.OS == "WINNT") {
// Windows rejects files if they don't have a drive. See Bug 1180870
fileprefix += "c:/";
}
// Add some permissions
let uri0 = NetUtil.newURI("http://google.com:9091/just/a/path", null, null);
let uri1 = NetUtil.newURI("http://hangouts.google.com:9091/some/path", null, null);
let uri2 = NetUtil.newURI("http://google.com:9091/", null, null);
let uri3 = NetUtil.newURI("http://google.org:9091/", null, null);
let uri4 = NetUtil.newURI("http://deeper.hangouts.google.com:9091/", null, null);
let uri5 = NetUtil.newURI("https://google.com/just/a/path", null, null);
let uri6 = NetUtil.newURI("https://hangouts.google.com", null, null);
let uri7 = NetUtil.newURI("https://google.com/", null, null);
let fileuri1 = NetUtil.newURI(fileprefix + "a/file/path", null, null);
let fileuri2 = NetUtil.newURI(fileprefix + "a/file/path/deeper", null, null);
let fileuri3 = NetUtil.newURI(fileprefix + "a/file/otherpath", null, null);
{
let perm = mk_permission(uri0);
matches_always(perm, [uri0, uri2]);
matches_weak(perm, [uri1, uri4]);
matches_never(perm, [uri3, uri5, uri6, uri7, fileuri1, fileuri2, fileuri3]);
}
{
let perm = mk_permission(uri1);
matches_always(perm, [uri1]);
matches_weak(perm, [uri4]);
matches_never(perm, [uri0, uri2, uri3, uri5, uri6, uri7, fileuri1, fileuri2, fileuri3]);
}
{
let perm = mk_permission(uri2);
matches_always(perm, [uri0, uri2]);
matches_weak(perm, [uri1, uri4]);
matches_never(perm, [uri3, uri5, uri6, uri7, fileuri1, fileuri2, fileuri3]);
}
{
let perm = mk_permission(uri3);
matches_always(perm, [uri3]);
matches_weak(perm, []);
matches_never(perm, [uri1, uri2, uri4, uri5, uri6, uri7, fileuri1, fileuri2, fileuri3]);
}
{
let perm = mk_permission(uri4);
matches_always(perm, [uri4]);
matches_weak(perm, []);
matches_never(perm, [uri1, uri2, uri3, uri5, uri6, uri7, fileuri1, fileuri2, fileuri3]);
}
{
let perm = mk_permission(uri5);
matches_always(perm, [uri5, uri7]);
matches_weak(perm, [uri6]);
matches_never(perm, [uri0, uri1, uri2, uri3, uri4, fileuri1, fileuri2, fileuri3]);
}
{
let perm = mk_permission(uri6);
matches_always(perm, [uri6]);
matches_weak(perm, []);
matches_never(perm, [uri0, uri1, uri2, uri3, uri4, uri5, uri7, fileuri1, fileuri2, fileuri3]);
}
{
let perm = mk_permission(uri7);
matches_always(perm, [uri5, uri7]);
matches_weak(perm, [uri6]);
matches_never(perm, [uri0, uri1, uri2, uri3, uri4, fileuri1, fileuri2, fileuri3]);
}
{
let perm = mk_permission(fileuri1);
matches_always(perm, [fileuri1]);
matches_weak(perm, []);
matches_never(perm, [uri0, uri1, uri2, uri3, uri4, uri5, uri6, uri7, fileuri2, fileuri3]);
}
{
let perm = mk_permission(fileuri2);
matches_always(perm, [fileuri2]);
matches_weak(perm, []);
matches_never(perm, [uri0, uri1, uri2, uri3, uri4, uri5, uri6, uri7, fileuri1, fileuri3]);
}
{
let perm = mk_permission(fileuri3);
matches_always(perm, [fileuri3]);
matches_weak(perm, []);
matches_never(perm, [uri0, uri1, uri2, uri3, uri4, uri5, uri6, uri7, fileuri1, fileuri2]);
}
// Clean up!
pm.removeAll();
}

View File

@ -1,162 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils",
"resource://testing-common/PlacesTestUtils.jsm");
let PERMISSIONS_FILE_NAME = "permissions.sqlite";
function GetPermissionsFile(profile)
{
let file = profile.clone();
file.append(PERMISSIONS_FILE_NAME);
return file;
}
function run_test() {
run_next_test();
}
add_task(function test() {
/* Create and set up the permissions database */
let profile = do_get_profile();
let db = Services.storage.openDatabase(GetPermissionsFile(profile));
db.schemaVersion = 4;
db.executeSimpleSQL(
"CREATE TABLE moz_hosts (" +
" id INTEGER PRIMARY KEY" +
",host TEXT" +
",type TEXT" +
",permission INTEGER" +
",expireType INTEGER" +
",expireTime INTEGER" +
",modificationTime INTEGER" +
",appId INTEGER" +
",isInBrowserElement INTEGER" +
")");
let stmtInsert = db.createStatement(
"INSERT INTO moz_hosts (" +
"id, host, type, permission, expireType, expireTime, modificationTime, appId, isInBrowserElement" +
") VALUES (" +
":id, :host, :type, :permission, :expireType, :expireTime, :modificationTime, :appId, :isInBrowserElement" +
")");
let id = 0;
function insertHost(host, type, permission, expireType, expireTime, modificationTime, appId, isInBrowserElement) {
stmtInsert.bindByName("id", id++);
stmtInsert.bindByName("host", host);
stmtInsert.bindByName("type", type);
stmtInsert.bindByName("permission", permission);
stmtInsert.bindByName("expireType", expireType);
stmtInsert.bindByName("expireTime", expireTime);
stmtInsert.bindByName("modificationTime", modificationTime);
stmtInsert.bindByName("appId", appId);
stmtInsert.bindByName("isInBrowserElement", isInBrowserElement);
try {
stmtInsert.executeStep();
stmtInsert.reset();
} catch (e) {
stmtInsert.reset();
throw e;
}
}
// Add some rows to the database
insertHost("foo.com", "A", 1, 0, 0, 0, 0, false);
insertHost("foo.com", "A", 1, 0, 0, 0, 1000, false);
insertHost("foo.com", "A", 1, 0, 0, 0, 2000, true);
insertHost("sub.foo.com", "B", 1, 0, 0, 0, 0, false);
insertHost("subber.sub.foo.com", "B", 1, 0, 0, 0, 0, false);
insertHost("bar.ca", "B", 1, 0, 0, 0, 0, false);
insertHost("bar.ca", "B", 1, 0, 0, 0, 1000, false);
insertHost("bar.ca", "A", 1, 0, 0, 0, 1000, true);
insertHost("file:///some/path/to/file.html", "A", 1, 0, 0, 0, 0, false);
insertHost("file:///another/file.html", "A", 1, 0, 0, 0, 0, false);
insertHost("moz-nullprincipal:{8695105a-adbe-4e4e-8083-851faa5ca2d7}", "A", 1, 0, 0, 0, 0, false);
insertHost("moz-nullprincipal:{12ahjksd-akjs-asd3-8393-asdu2189asdu}", "B", 1, 0, 0, 0, 0, false);
insertHost("<file>", "A", 1, 0, 0, 0, 0, false);
insertHost("<file>", "B", 1, 0, 0, 0, 0, false);
// CLose the db connection
stmtInsert.finalize();
db.close();
stmtInsert = null;
db = null;
let expected = [
// The http:// entries under foo.com won't be inserted, as there are history entries for foo.com,
// and http://foo.com or a subdomain are never visited.
// However, permissions for subdomains of foo.com will be present for both http:// and https://,
// as they do not apply to any entry in the history
// ["http://foo.com", "A", 1, 0, 0],
// ["http://foo.com^appId=1000", "A", 1, 0, 0],
// ["http://foo.com^appId=2000&inBrowser=1", "A", 1, 0, 0],
["http://sub.foo.com", "B", 1, 0, 0],
["http://subber.sub.foo.com", "B", 1, 0, 0],
["https://foo.com", "A", 1, 0, 0],
["https://foo.com^appId=1000", "A", 1, 0, 0],
["https://foo.com^appId=2000&inBrowser=1", "A", 1, 0, 0],
["https://sub.foo.com", "B", 1, 0, 0],
["https://subber.sub.foo.com", "B", 1, 0, 0],
// bar.ca will have both http:// and https:// for all entries, because the foo did the bar a favour
["http://bar.ca", "B", 1, 0, 0],
["https://bar.ca", "B", 1, 0, 0],
["http://bar.ca^appId=1000", "B", 1, 0, 0],
["https://bar.ca^appId=1000", "B", 1, 0, 0],
["http://bar.ca^appId=1000&inBrowser=1", "A", 1, 0, 0],
["https://bar.ca^appId=1000&inBrowser=1", "A", 1, 0, 0],
["file:///some/path/to/file.html", "A", 1, 0, 0],
["file:///another/file.html", "A", 1, 0, 0],
// Because we put ftp://some.subdomain.of.foo.com:8000/some/subdirectory in the history, we should
// also have these entries
["ftp://foo.com:8000", "A", 1, 0, 0],
["ftp://foo.com:8000^appId=1000", "A", 1, 0, 0],
["ftp://foo.com:8000^appId=2000&inBrowser=1", "A", 1, 0, 0],
];
let found = expected.map((it) => 0);
// Add some places to the places database
yield PlacesTestUtils.addVisits(Services.io.newURI("https://foo.com/some/other/subdirectory", null, null));
yield PlacesTestUtils.addVisits(Services.io.newURI("ftp://some.subdomain.of.foo.com:8000/some/subdirectory", null, null));
// Force initialization of the nsPermissionManager
let enumerator = Services.perms.enumerator;
while (enumerator.hasMoreElements()) {
let permission = enumerator.getNext().QueryInterface(Ci.nsIPermission);
let isExpected = false;
expected.forEach((it, i) => {
if (permission.principal.origin == it[0] &&
permission.type == it[1] &&
permission.capability == it[2] &&
permission.expireType == it[3] &&
permission.expireTime == it[4]) {
isExpected = true;
found[i]++;
}
});
do_check_true(isExpected,
"Permission " + (isExpected ? "should" : "shouldn't") +
" be in permission database: " +
permission.principal.origin + ", " +
permission.type + ", " +
permission.capability + ", " +
permission.expireType + ", " +
permission.expireTime);
}
found.forEach((count, i) => {
do_check_true(count == 1, "Expected count = 1, got count = " + count + " for permission " + expected[i]);
});
});

View File

@ -30,10 +30,8 @@ skip-if = debug == true
[test_permmanager_idn.js] [test_permmanager_idn.js]
[test_permmanager_subdomains.js] [test_permmanager_subdomains.js]
[test_permmanager_local_files.js] [test_permmanager_local_files.js]
[test_permmanager_mailto.js]
[test_permmanager_cleardata.js] [test_permmanager_cleardata.js]
[test_schema_2_migration.js] [test_schema_2_migration.js]
[test_schema_3_migration.js] [test_schema_3_migration.js]
[test_permmanager_removepermission.js] [test_permmanager_removepermission.js]
[test_permmanager_matchesuri.js]
[test_permmanager_matches.js]
[test_permmanager_migrate_4-5.js]

View File

@ -65,6 +65,3 @@
// Disable periodic updates of service workers. // Disable periodic updates of service workers.
branch.setBoolPref("dom.serviceWorkers.periodic-updates.enabled", false); branch.setBoolPref("dom.serviceWorkers.periodic-updates.enabled", false);
// Allow XUL and XBL files to be opened from file:// URIs
branch.setBoolPref("dom.allow_XUL_XBL_for_file", true);

View File

@ -1177,9 +1177,6 @@ function ServeFiles(manifestPrincipal, depth, aURL, files)
var testbase = gIOService.newURI("http://localhost:" + gHttpServerPort + var testbase = gIOService.newURI("http://localhost:" + gHttpServerPort +
path + dirPath, null, null); path + dirPath, null, null);
// Give the testbase URI access to XUL and XBL
Services.perms.add(testbase, "allowXULXBL", Services.perms.ALLOW_ACTION);
function FileToURI(file) function FileToURI(file)
{ {
// Only serve relative URIs via the HTTP server, not absolute // Only serve relative URIs via the HTTP server, not absolute

View File

@ -342,7 +342,7 @@ class RemoteReftest(RefTest):
self.server.stop() self.server.stop()
def createReftestProfile(self, options, reftestlist): def createReftestProfile(self, options, reftestlist):
profile = RefTest.createReftestProfile(self, options, reftestlist, server=options.remoteWebServer, port=options.httpPort) profile = RefTest.createReftestProfile(self, options, reftestlist, server=options.remoteWebServer)
profileDir = profile.profile profileDir = profile.profile
prefs = {} prefs = {}

View File

@ -187,8 +187,8 @@ class RefTest(object):
""" """
locations = mozprofile.permissions.ServerLocations() locations = mozprofile.permissions.ServerLocations()
locations.add_host(server, scheme='http', port=0) locations.add_host(server, port=0)
locations.add_host(server, scheme='https', port=0) locations.add_host('<file>', port=0)
# Set preferences for communication between our command line arguments # Set preferences for communication between our command line arguments
# and the reftest harness. Preferences that are required for reftest # and the reftest harness. Preferences that are required for reftest

View File

@ -177,8 +177,8 @@ pref("dom.forms.number", true);
/* extension manager and xpinstall */ /* extension manager and xpinstall */
pref("xpinstall.whitelist.directRequest", false); pref("xpinstall.whitelist.directRequest", false);
pref("xpinstall.whitelist.fileRequest", false); pref("xpinstall.whitelist.fileRequest", false);
pref("xpinstall.whitelist.add", "https://addons.mozilla.org"); pref("xpinstall.whitelist.add", "addons.mozilla.org");
pref("xpinstall.whitelist.add.180", "https://marketplace.firefox.com"); pref("xpinstall.whitelist.add.180", "marketplace.firefox.com");
pref("xpinstall.signatures.required", false); pref("xpinstall.signatures.required", false);

View File

@ -1751,11 +1751,11 @@ var BrowserApp = {
docShell.mixedContentChannel = null; docShell.mixedContentChannel = null;
} }
} else if (data.contentType === "tracking") { } else if (data.contentType === "tracking") {
// Convert document URI into the format used by
// nsChannelClassifier::ShouldEnableTrackingProtection
// (any scheme turned into https is correct)
let normalizedUrl = Services.io.newURI("https://" + browser.currentURI.hostPort, null, null);
if (data.allowContent) { if (data.allowContent) {
// Convert document URI into the format used by
// nsChannelClassifier::ShouldEnableTrackingProtection
// (any scheme turned into https is correct)
let normalizedUrl = Services.io.newURI("https://" + browser.currentURI.hostPort, null, null);
// Add the current host in the 'trackingprotection' consumer of // Add the current host in the 'trackingprotection' consumer of
// the permission manager using a normalized URI. This effectively // the permission manager using a normalized URI. This effectively
// places this host on the tracking protection white list. // places this host on the tracking protection white list.
@ -1765,7 +1765,7 @@ var BrowserApp = {
// Remove the current host from the 'trackingprotection' consumer // Remove the current host from the 'trackingprotection' consumer
// of the permission manager. This effectively removes this host // of the permission manager. This effectively removes this host
// from the tracking protection white list (any list actually). // from the tracking protection white list (any list actually).
Services.perms.remove(normalizedUrl, "trackingprotection"); Services.perms.remove(browser.currentURI, "trackingprotection");
Telemetry.addData("TRACKING_PROTECTION_EVENTS", 2); Telemetry.addData("TRACKING_PROTECTION_EVENTS", 2);
} }
} }

View File

@ -6,10 +6,7 @@
#include "nsISupports.idl" #include "nsISupports.idl"
interface nsIPrincipal; [scriptable, uuid(cfb08e46-193c-4be7-a467-d7775fb2a31e)]
interface nsIURI;
[scriptable, uuid(bb409a51-2371-4fea-9dc9-b7286a458b8c)]
/** /**
* This interface defines a "permission" object, * This interface defines a "permission" object,
* used to specify allowed/blocked objects from * used to specify allowed/blocked objects from
@ -19,9 +16,19 @@ interface nsIURI;
interface nsIPermission : nsISupports interface nsIPermission : nsISupports
{ {
/** /**
* The principal for which this permission applies. * The name of the host for which the permission is set
*/ */
readonly attribute nsIPrincipal principal; readonly attribute AUTF8String host;
/**
* The id of the app for which the permission is set.
*/
readonly attribute unsigned long appId;
/**
* Whether the permission has been set to a page inside a browser element.
*/
readonly attribute boolean isInBrowserElement;
/** /**
* a case-sensitive ASCII string, indicating the type of permission * a case-sensitive ASCII string, indicating the type of permission
@ -49,29 +56,4 @@ interface nsIPermission : nsISupports
* 0:00:00). * 0:00:00).
*/ */
readonly attribute int64_t expireTime; readonly attribute int64_t expireTime;
/**
* Test whether a principal would be affected by this permission.
*
* @param principal the principal to test
* @param exactHost If true, only the specific host will be matched,
* @see nsIPermissionManager::testExactPermission.
* If false, subdomains will also be searched,
* @see nsIPermissionManager::testPermission.
*/
boolean matches(in nsIPrincipal principal,
in boolean exactHost);
/**
* Test whether a URI would be affected by this permission.
* This performs a matches with a NO_APP_ID identifier.
*
* @param uri the uri to test
* @param exactHost If true, only the specific host will be matched,
* @see nsIPermissionManager::testExactPermission.
* If false, subdomains will also be searched,
* @see nsIPermissionManager::testPermission.
*/
boolean matchesURI(in nsIURI uri,
in boolean exactHost);
}; };

View File

@ -20,20 +20,26 @@ namespace IPC {
struct Permission struct Permission
{ {
nsCString origin, type; nsCString host, type;
uint32_t capability, expireType; uint32_t capability, expireType;
int64_t expireTime; int64_t expireTime;
uint32_t appId;
bool isInBrowserElement;
Permission() { } Permission() { }
Permission(const nsCString& aOrigin, Permission(const nsCString& aHost,
const uint32_t aAppId,
const bool aIsInBrowserElement,
const nsCString& aType, const nsCString& aType,
const uint32_t aCapability, const uint32_t aCapability,
const uint32_t aExpireType, const uint32_t aExpireType,
const int64_t aExpireTime) : origin(aOrigin), const int64_t aExpireTime) : host(aHost),
type(aType), type(aType),
capability(aCapability), capability(aCapability),
expireType(aExpireType), expireType(aExpireType),
expireTime(aExpireTime) expireTime(aExpireTime),
appId(aAppId),
isInBrowserElement(aIsInBrowserElement)
{} {}
}; };
@ -42,26 +48,34 @@ struct ParamTraits<Permission>
{ {
static void Write(Message* aMsg, const Permission& aParam) static void Write(Message* aMsg, const Permission& aParam)
{ {
WriteParam(aMsg, aParam.origin); WriteParam(aMsg, aParam.host);
WriteParam(aMsg, aParam.type); WriteParam(aMsg, aParam.type);
WriteParam(aMsg, aParam.capability); WriteParam(aMsg, aParam.capability);
WriteParam(aMsg, aParam.expireType); WriteParam(aMsg, aParam.expireType);
WriteParam(aMsg, aParam.expireTime); WriteParam(aMsg, aParam.expireTime);
WriteParam(aMsg, aParam.appId);
WriteParam(aMsg, aParam.isInBrowserElement);
} }
static bool Read(const Message* aMsg, void** aIter, Permission* aResult) static bool Read(const Message* aMsg, void** aIter, Permission* aResult)
{ {
return ReadParam(aMsg, aIter, &aResult->origin) && return ReadParam(aMsg, aIter, &aResult->host) &&
ReadParam(aMsg, aIter, &aResult->type) && ReadParam(aMsg, aIter, &aResult->type) &&
ReadParam(aMsg, aIter, &aResult->capability) && ReadParam(aMsg, aIter, &aResult->capability) &&
ReadParam(aMsg, aIter, &aResult->expireType) && ReadParam(aMsg, aIter, &aResult->expireType) &&
ReadParam(aMsg, aIter, &aResult->expireTime); ReadParam(aMsg, aIter, &aResult->expireTime) &&
ReadParam(aMsg, aIter, &aResult->appId) &&
ReadParam(aMsg, aIter, &aResult->isInBrowserElement);
} }
static void Log(const Permission& p, std::wstring* l) static void Log(const Permission& p, std::wstring* l)
{ {
l->append(L"("); l->append(L"(");
LogParam(p.origin, l); LogParam(p.host, l);
l->append(L", ");
LogParam(p.appId, l);
l->append(L", ");
LogParam(p.isInBrowserElement, l);
l->append(L", "); l->append(L", ");
LogParam(p.capability, l); LogParam(p.capability, l);
l->append(L", "); l->append(L", ");

View File

@ -2,31 +2,31 @@
var hosts = [ var hosts = [
// format: [host, type, permission] // format: [host, type, permission]
["http://mozilla.org", "cookie", 1], ["mozilla.org", "cookie", 1],
["http://mozilla.org", "image", 2], ["mozilla.org", "image", 2],
["http://mozilla.org", "popup", 3], ["mozilla.org", "popup", 3],
["http://mozilla.com", "cookie", 1], ["mozilla.com", "cookie", 1],
["http://www.mozilla.com", "cookie", 2], ["www.mozilla.com", "cookie", 2],
["http://dev.mozilla.com", "cookie", 3] ["dev.mozilla.com", "cookie", 3]
]; ];
var results = [ var results = [
// format: [host, type, testPermission result, testExactPermission result] // format: [host, type, testPermission result, testExactPermission result]
// test defaults // test defaults
["http://localhost", "cookie", 0, 0], ["localhost", "cookie", 0, 0],
["http://spreadfirefox.com", "cookie", 0, 0], ["spreadfirefox.com", "cookie", 0, 0],
// test different types // test different types
["http://mozilla.org", "cookie", 1, 1], ["mozilla.org", "cookie", 1, 1],
["http://mozilla.org", "image", 2, 2], ["mozilla.org", "image", 2, 2],
["http://mozilla.org", "popup", 3, 3], ["mozilla.org", "popup", 3, 3],
// test subdomains // test subdomains
["http://www.mozilla.org", "cookie", 1, 0], ["www.mozilla.org", "cookie", 1, 0],
["http://www.dev.mozilla.org", "cookie", 1, 0], ["www.dev.mozilla.org", "cookie", 1, 0],
// test different permissions on subdomains // test different permissions on subdomains
["http://mozilla.com", "cookie", 1, 1], ["mozilla.com", "cookie", 1, 1],
["http://www.mozilla.com", "cookie", 2, 2], ["www.mozilla.com", "cookie", 2, 2],
["http://dev.mozilla.com", "cookie", 3, 3], ["dev.mozilla.com", "cookie", 3, 3],
["http://www.dev.mozilla.com", "cookie", 3, 0] ["www.dev.mozilla.com", "cookie", 3, 0]
]; ];
function run_test() { function run_test() {
@ -45,16 +45,16 @@ function run_test() {
// put a few hosts in // put a few hosts in
for (var i = 0; i < hosts.length; ++i) { for (var i = 0; i < hosts.length; ++i) {
let uri = ioService.newURI(hosts[i][0], null, null); var uri = ioService.newURI("http://" + hosts[i][0], null, null);
let principal = secMan.getNoAppCodebasePrincipal(uri); var principal = secMan.getNoAppCodebasePrincipal(uri);
pm.addFromPrincipal(principal, hosts[i][1], hosts[i][2]); pm.addFromPrincipal(principal, hosts[i][1], hosts[i][2]);
} }
// test the result // test the result
for (var i = 0; i < results.length; ++i) { for (var i = 0; i < results.length; ++i) {
let uri = ioService.newURI(results[i][0], null, null); var uri = ioService.newURI("http://" + results[i][0], null, null);
let principal = secMan.getNoAppCodebasePrincipal(uri); var principal = secMan.getNoAppCodebasePrincipal(uri);
do_check_eq(pm.testPermissionFromPrincipal(principal, results[i][1]), results[i][2]); do_check_eq(pm.testPermissionFromPrincipal(principal, results[i][1]), results[i][2]);
do_check_eq(pm.testExactPermissionFromPrincipal(principal, results[i][1]), results[i][3]); do_check_eq(pm.testExactPermissionFromPrincipal(principal, results[i][1]), results[i][3]);
@ -72,13 +72,16 @@ function run_test() {
// ... remove all the hosts ... // ... remove all the hosts ...
for (var j = 0; j < perms.length; ++j) { for (var j = 0; j < perms.length; ++j) {
pm.removePermission(perms[j]); var uri = ioService.newURI("http://" + perms[j].host, null, null);
var principal = secMan.getNoAppCodebasePrincipal(uri);
pm.removeFromPrincipal(principal, perms[j].type);
} }
// ... ensure each and every element is equal ... // ... ensure each and every element is equal ...
for (var i = 0; i < hosts.length; ++i) { for (var i = 0; i < hosts.length; ++i) {
for (var j = 0; j < perms.length; ++j) { for (var j = 0; j < perms.length; ++j) {
if (perms[j].matchesURI(ioService.newURI(hosts[i][0], null, null), true) && if (hosts[i][0] == perms[j].host &&
hosts[i][1] == perms[j].type && hosts[i][1] == perms[j].type &&
hosts[i][2] == perms[j].capability) { hosts[i][2] == perms[j].capability) {
perms.splice(j, 1); perms.splice(j, 1);
@ -99,7 +102,7 @@ function run_test() {
var enumerator = pm.enumerator; var enumerator = pm.enumerator;
do_check_eq(enumerator.hasMoreElements(), true); do_check_eq(enumerator.hasMoreElements(), true);
var ace = enumerator.getNext().QueryInterface(Components.interfaces.nsIPermission); var ace = enumerator.getNext().QueryInterface(Components.interfaces.nsIPermission);
do_check_eq(ace.principal.URI.asciiHost, aceref); do_check_eq(ace.host, aceref);
do_check_eq(enumerator.hasMoreElements(), false); do_check_eq(enumerator.hasMoreElements(), false);
// test removeAll() // test removeAll()

View File

@ -231,26 +231,18 @@ class Permissions(object):
# SQL copied from # SQL copied from
# http://mxr.mozilla.org/mozilla-central/source/extensions/cookie/nsPermissionManager.cpp # http://mxr.mozilla.org/mozilla-central/source/extensions/cookie/nsPermissionManager.cpp
cursor.execute("""CREATE TABLE IF NOT EXISTS moz_hosts ( cursor.execute("""CREATE TABLE IF NOT EXISTS moz_hosts (
id INTEGER PRIMARY KEY id INTEGER PRIMARY KEY,
,origin TEXT host TEXT,
,type TEXT type TEXT,
,permission INTEGER permission INTEGER,
,expireType INTEGER expireType INTEGER,
,expireTime INTEGER expireTime INTEGER)""")
,modificationTime INTEGER
)""")
rows = cursor.execute("PRAGMA table_info(moz_hosts)") rows = cursor.execute("PRAGMA table_info(moz_hosts)")
count = len(rows.fetchall()) count = len(rows.fetchall())
using_origin = False
# if the db contains 7 columns, we're using user_version 5
if count == 7:
statement = "INSERT INTO moz_hosts values(NULL, ?, ?, ?, 0, 0, 0)"
cursor.execute("PRAGMA user_version=5;")
using_origin = True
# if the db contains 9 columns, we're using user_version 4 # if the db contains 9 columns, we're using user_version 4
elif count == 9: if count == 9:
statement = "INSERT INTO moz_hosts values(NULL, ?, ?, ?, 0, 0, 0, 0, 0)" statement = "INSERT INTO moz_hosts values(NULL, ?, ?, ?, 0, 0, 0, 0, 0)"
cursor.execute("PRAGMA user_version=4;") cursor.execute("PRAGMA user_version=4;")
# if the db contains 8 columns, we're using user_version 3 # if the db contains 8 columns, we're using user_version 3
@ -270,26 +262,8 @@ class Permissions(object):
else: else:
permission_type = 2 permission_type = 2
if using_origin: cursor.execute(statement,
# This is a crude approximation of the origin generation logic from (location.host, perm, permission_type))
# nsPrincipal and nsStandardURL. It should suffice for the permissions
# which the test runners will want to insert into the system.
origin = location.scheme + "://" + location.host
if (location.scheme != 'http' or location.port != '80') and \
(location.scheme != 'https' or location.port != '443'):
origin += ':' + str(location.port)
cursor.execute(statement,
(origin, perm, permission_type))
else:
# The database is still using a legacy system based on hosts
# We can insert the permission as a host
#
# XXX This codepath should not be hit, as tests are run with
# fresh profiles. However, if it was hit, permissions would
# not be added to the database correctly (bug 1183185).
cursor.execute(statement,
(location.host, perm, permission_type))
# Commit and close # Commit and close
permDB.commit() permDB.commit()

View File

@ -44,7 +44,7 @@ http://127.0.0.1:8888 privileged
entries = cur.fetchall() entries = cur.fetchall()
schema_version = entries[0][0] schema_version = entries[0][0]
self.assertEqual(schema_version, 5) self.assertEqual(schema_version, 2)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -40,16 +40,7 @@ http://127.0.0.1:8888 privileged
cursor.execute("PRAGMA user_version=%d;" % version) cursor.execute("PRAGMA user_version=%d;" % version)
if version == 5: if version == 4:
cursor.execute("""CREATE TABLE IF NOT EXISTS moz_hosts (
id INTEGER PRIMARY KEY,
origin TEXT,
type TEXT,
permission INTEGER,
expireType INTEGER,
expireTime INTEGER,
modificationTime INTEGER)""")
elif version == 4:
cursor.execute("""CREATE TABLE IF NOT EXISTS moz_hosts ( cursor.execute("""CREATE TABLE IF NOT EXISTS moz_hosts (
id INTEGER PRIMARY KEY, id INTEGER PRIMARY KEY,
host TEXT, host TEXT,
@ -79,7 +70,7 @@ http://127.0.0.1:8888 privileged
expireType INTEGER, expireType INTEGER,
expireTime INTEGER)""") expireTime INTEGER)""")
else: else:
raise Exception("version must be 2, 3, 4 or 5") raise Exception("version must be 2, 3 or 4")
permDB.commit() permDB.commit()
cursor.close() cursor.close()
@ -88,7 +79,7 @@ http://127.0.0.1:8888 privileged
perms = Permissions(self.profile_dir, self.locations_file.name) perms = Permissions(self.profile_dir, self.locations_file.name)
perms_db_filename = os.path.join(self.profile_dir, 'permissions.sqlite') perms_db_filename = os.path.join(self.profile_dir, 'permissions.sqlite')
select_stmt = 'select origin, type, permission from moz_hosts' select_stmt = 'select host, type, permission from moz_hosts'
con = sqlite3.connect(perms_db_filename) con = sqlite3.connect(perms_db_filename)
cur = con.cursor() cur = con.cursor()
@ -97,32 +88,32 @@ http://127.0.0.1:8888 privileged
self.assertEqual(len(entries), 3) self.assertEqual(len(entries), 3)
self.assertEqual(entries[0][0], 'http://mochi.test:8888') self.assertEqual(entries[0][0], 'mochi.test')
self.assertEqual(entries[0][1], 'allowXULXBL') self.assertEqual(entries[0][1], 'allowXULXBL')
self.assertEqual(entries[0][2], 1) self.assertEqual(entries[0][2], 1)
self.assertEqual(entries[1][0], 'http://127.0.0.1') self.assertEqual(entries[1][0], '127.0.0.1')
self.assertEqual(entries[1][1], 'allowXULXBL') self.assertEqual(entries[1][1], 'allowXULXBL')
self.assertEqual(entries[1][2], 2) self.assertEqual(entries[1][2], 2)
self.assertEqual(entries[2][0], 'http://127.0.0.1:8888') self.assertEqual(entries[2][0], '127.0.0.1')
self.assertEqual(entries[2][1], 'allowXULXBL') self.assertEqual(entries[2][1], 'allowXULXBL')
self.assertEqual(entries[2][2], 1) self.assertEqual(entries[2][2], 1)
perms._locations.add_host('a.b.c', port='8081', scheme='https', options='noxul') perms._locations.add_host('a.b.c', options='noxul')
cur.execute(select_stmt) cur.execute(select_stmt)
entries = cur.fetchall() entries = cur.fetchall()
self.assertEqual(len(entries), 4) self.assertEqual(len(entries), 4)
self.assertEqual(entries[3][0], 'https://a.b.c:8081') self.assertEqual(entries[3][0], 'a.b.c')
self.assertEqual(entries[3][1], 'allowXULXBL') self.assertEqual(entries[3][1], 'allowXULXBL')
self.assertEqual(entries[3][2], 2) self.assertEqual(entries[3][2], 2)
# when creating a DB we should default to user_version==5 # when creating a DB we should default to user_version==2
cur.execute('PRAGMA user_version') cur.execute('PRAGMA user_version')
entries = cur.fetchall() entries = cur.fetchall()
self.assertEqual(entries[0][0], 5) self.assertEqual(entries[0][0], 2)
perms.clean_db() perms.clean_db()
# table should be removed # table should be removed
@ -169,14 +160,7 @@ http://127.0.0.1:8888 privileged
self.assertEqual(len(entries), 3) self.assertEqual(len(entries), 3)
columns = { columns = 9 if version == 4 else (8 if version == 3 else 6)
1: 6,
2: 6,
3: 8,
4: 9,
5: 7,
}[version]
self.assertEqual(len(entries[0]), columns) self.assertEqual(len(entries[0]), columns)
for x in range(4, columns): for x in range(4, columns):
self.assertEqual(entries[0][x], 0) self.assertEqual(entries[0][x], 0)
@ -190,8 +174,5 @@ http://127.0.0.1:8888 privileged
def test_existing_permissions_db_v4(self): def test_existing_permissions_db_v4(self):
self.verify_user_version(4) self.verify_user_version(4)
def test_existing_permissions_db_v5(self):
self.verify_user_version(5)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -217,16 +217,7 @@ SpecialPowersObserver.prototype = new SpecialPowersObserverAPI();
switch (aTopic) { switch (aTopic) {
case "perm-changed": case "perm-changed":
var permission = aSubject.QueryInterface(Ci.nsIPermission); var permission = aSubject.QueryInterface(Ci.nsIPermission);
msg.permission = { appId: permission.appId, type: permission.type };
// specialPowersAPI will consume this value, and it is used as a
// fake permission, but only type and principal.appId will be used.
//
// We need to ensure that it looks the same as a real permission,
// so we fake these properties.
msg.permission = {
principal: { appId: permission.principal.appId },
type: permission.type
};
default: default:
this._self._sendAsyncMessage("specialpowers-" + aTopic, msg); this._self._sendAsyncMessage("specialpowers-" + aTopic, msg);
} }

View File

@ -967,7 +967,7 @@ SpecialPowersAPI.prototype = {
for (var j = 0; j < undos.length; j++) { for (var j = 0; j < undos.length; j++) {
var undo = undos[j]; var undo = undos[j];
if (undo.op == this._obsDataMap[aData] && if (undo.op == this._obsDataMap[aData] &&
undo.appId == permission.principal.appId && undo.appId == permission.appId &&
undo.type == permission.type) { undo.type == permission.type) {
// Remove this undo item if it has been done by others(not // Remove this undo item if it has been done by others(not
// specialpowers itself.) // specialpowers itself.)

View File

@ -140,13 +140,8 @@ this.ForgetAboutSite = {
enumerator = pm.enumerator; enumerator = pm.enumerator;
while (enumerator.hasMoreElements()) { while (enumerator.hasMoreElements()) {
let perm = enumerator.getNext().QueryInterface(Ci.nsIPermission); let perm = enumerator.getNext().QueryInterface(Ci.nsIPermission);
try { if (hasRootDomain(perm.host, aDomain))
if (hasRootDomain(perm.principal.URI.host, aDomain)) { pm.removePermission(perm);
pm.removePermission(perm);
}
} catch (e) {
/* Ignore entry */
}
} }
// Offline Storages // Offline Storages

View File

@ -105,7 +105,7 @@ this.BrowserUtils = {
throw new Error("principalFromOrigin does not support nsNullPrincipal"); throw new Error("principalFromOrigin does not support nsNullPrincipal");
} }
var parts = aOriginString.split('^'); var parts = aOriginString.split('!');
if (parts.length > 2) { if (parts.length > 2) {
throw new Error("bad origin string: " + aOriginString); throw new Error("bad origin string: " + aOriginString);
} }

View File

@ -7,7 +7,6 @@ this.EXPORTED_SYMBOLS = ["PermissionsUtils"];
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/BrowserUtils.jsm")
let gImportedPrefBranches = new Set(); let gImportedPrefBranches = new Set();
@ -16,40 +15,29 @@ function importPrefBranch(aPrefBranch, aPermission, aAction) {
let list = Services.prefs.getChildList(aPrefBranch, {}); let list = Services.prefs.getChildList(aPrefBranch, {});
for (let pref of list) { for (let pref of list) {
let origins = ""; let hosts = "";
try { try {
origins = Services.prefs.getCharPref(pref); hosts = Services.prefs.getCharPref(pref);
} catch (e) {} } catch (e) {}
if (!origins) if (!hosts)
continue; continue;
origins = origins.split(","); hosts = hosts.split(",");
for (let origin of origins) { for (let host of hosts) {
let principals = []; let uri = null;
try { try {
principals = [ BrowserUtils.principalFromOrigin(origin) ]; uri = Services.io.newURI("http://" + host, null, null);
} catch (e) { } catch (e) {
// This preference used to contain a list of hosts. For back-compat
// reasons, we convert these hosts into http:// and https:// permissions
// on default ports.
try { try {
let httpURI = Services.io.newURI("http://" + origin, null, null); uri = Services.io.newURI(host, null, null);
let httpsURI = Services.io.newURI("https://" + origin, null, null);
principals = [
Services.scriptSecurityManager.getNoAppCodebasePrincipal(httpURI),
Services.scriptSecurityManager.getNoAppCodebasePrincipal(httpsURI)
];
} catch (e2) {} } catch (e2) {}
} }
for (let principal of principals) { try {
try { Services.perms.add(uri, aPermission, aAction);
Services.perms.addFromPrincipal(principal, aPermission, aAction); } catch (e) {}
} catch (e) {}
}
} }
Services.prefs.setCharPref(pref, ""); Services.prefs.setCharPref(pref, "");

View File

@ -23,36 +23,22 @@ function test_importfromPrefs() {
// Create own preferences to test // Create own preferences to test
Services.prefs.setCharPref(PREF_ROOT + "whitelist.add.EMPTY", ""); Services.prefs.setCharPref(PREF_ROOT + "whitelist.add.EMPTY", "");
Services.prefs.setCharPref(PREF_ROOT + "whitelist.add.EMPTY2", ","); Services.prefs.setCharPref(PREF_ROOT + "whitelist.add.EMPTY2", ",");
Services.prefs.setCharPref(PREF_ROOT + "whitelist.add.TEST", "http://whitelist.example.com"); Services.prefs.setCharPref(PREF_ROOT + "whitelist.add.TEST", "whitelist.example.com");
Services.prefs.setCharPref(PREF_ROOT + "whitelist.add.TEST2", "https://whitelist2-1.example.com,http://whitelist2-2.example.com:8080,about:home"); Services.prefs.setCharPref(PREF_ROOT + "whitelist.add.TEST2", "whitelist2-1.example.com,whitelist2-2.example.com,about:home");
Services.prefs.setCharPref(PREF_ROOT + "whitelist.add.TEST3", "whitelist3-1.example.com,about:config"); // legacy style - host only
Services.prefs.setCharPref(PREF_ROOT + "blacklist.add.EMPTY", ""); Services.prefs.setCharPref(PREF_ROOT + "blacklist.add.EMPTY", "");
Services.prefs.setCharPref(PREF_ROOT + "blacklist.add.TEST", "http://blacklist.example.com,"); Services.prefs.setCharPref(PREF_ROOT + "blacklist.add.TEST", "blacklist.example.com,");
Services.prefs.setCharPref(PREF_ROOT + "blacklist.add.TEST2", ",https://blacklist2-1.example.com,http://blacklist2-2.example.com:8080,about:mozilla"); Services.prefs.setCharPref(PREF_ROOT + "blacklist.add.TEST2", ",blacklist2-1.example.com,blacklist2-2.example.com,about:mozilla");
Services.prefs.setCharPref(PREF_ROOT + "blacklist.add.TEST3", "blacklist3-1.example.com,about:preferences"); // legacy style - host only
// Check they are unknown in the permission manager prior to importing. // Check they are unknown in the permission manager prior to importing.
let whitelisted = ["http://whitelist.example.com", let whitelisted = ["http://whitelist.example.com",
"https://whitelist2-1.example.com", "http://whitelist2-1.example.com",
"http://whitelist2-2.example.com:8080", "http://whitelist2-2.example.com",
"http://whitelist3-1.example.com",
"https://whitelist3-1.example.com",
"about:config",
"about:home"]; "about:home"];
let blacklisted = ["http://blacklist.example.com", let blacklisted = ["http://blacklist.example.com",
"https://blacklist2-1.example.com", "http://blacklist2-1.example.com",
"http://blacklist2-2.example.com:8080", "http://blacklist2-2.example.com",
"http://blacklist3-1.example.com",
"https://blacklist3-1.example.com",
"about:preferences",
"about:mozilla"]; "about:mozilla"];
let untouched = ["https://whitelist.example.com", let unknown = whitelisted.concat(blacklisted);
"https://blacklist.example.com",
"http://whitelist2-1.example.com",
"http://blacklist2-1.example.com",
"https://whitelist2-2.example.com:8080",
"https://blacklist2-2.example.com:8080"];
let unknown = whitelisted.concat(blacklisted).concat(untouched);
for (let url of unknown) { for (let url of unknown) {
let uri = Services.io.newURI(url, null, null); let uri = Services.io.newURI(url, null, null);
do_check_eq(Services.perms.testPermission(uri, TEST_PERM), Services.perms.UNKNOWN_ACTION); do_check_eq(Services.perms.testPermission(uri, TEST_PERM), Services.perms.UNKNOWN_ACTION);
@ -78,8 +64,4 @@ function test_importfromPrefs() {
let uri = Services.io.newURI(url, null, null); let uri = Services.io.newURI(url, null, null);
do_check_eq(Services.perms.testPermission(uri, TEST_PERM), Services.perms.DENY_ACTION); do_check_eq(Services.perms.testPermission(uri, TEST_PERM), Services.perms.DENY_ACTION);
} }
for (let url of untouched) {
let uri = Services.io.newURI(url, null, null);
do_check_eq(Services.perms.testPermission(uri, TEST_PERM), Services.perms.UNKNOWN_ACTION);
}
} }

View File

@ -12,9 +12,9 @@ const XPI_MIMETYPE = "application/x-xpinstall";
function run_test() { function run_test() {
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "2", "2"); createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "2", "2");
Services.prefs.setCharPref("xpinstall.whitelist.add", "https://test1.com,https://test2.com"); Services.prefs.setCharPref("xpinstall.whitelist.add", "test1.com,test2.com");
Services.prefs.setCharPref("xpinstall.whitelist.add.36", "https://test3.com,https://www.test4.com"); Services.prefs.setCharPref("xpinstall.whitelist.add.36", "test3.com,www.test4.com");
Services.prefs.setCharPref("xpinstall.whitelist.add.test5", "https://test5.com"); Services.prefs.setCharPref("xpinstall.whitelist.add.test5", "test5.com");
Services.perms.add(NetUtil.newURI("https://www.test9.com"), "install", Services.perms.add(NetUtil.newURI("https://www.test9.com"), "install",
AM_Ci.nsIPermissionManager.ALLOW_ACTION); AM_Ci.nsIPermissionManager.ALLOW_ACTION);

View File

@ -30,9 +30,9 @@ function run_test() {
// Create own preferences to test // Create own preferences to test
Services.prefs.setCharPref("xpinstall.whitelist.add.EMPTY", ""); Services.prefs.setCharPref("xpinstall.whitelist.add.EMPTY", "");
Services.prefs.setCharPref("xpinstall.whitelist.add.TEST", "http://whitelist.example.com"); Services.prefs.setCharPref("xpinstall.whitelist.add.TEST", "whitelist.example.com");
Services.prefs.setCharPref("xpinstall.blacklist.add.EMPTY", ""); Services.prefs.setCharPref("xpinstall.blacklist.add.EMPTY", "");
Services.prefs.setCharPref("xpinstall.blacklist.add.TEST", "http://blacklist.example.com"); Services.prefs.setCharPref("xpinstall.blacklist.add.TEST", "blacklist.example.com");
// Get list of preferences to check // Get list of preferences to check
var whitelistPreferences = Services.prefs.getChildList(PREF_XPI_WHITELIST_PERMISSIONS, {}); var whitelistPreferences = Services.prefs.getChildList(PREF_XPI_WHITELIST_PERMISSIONS, {});
@ -53,19 +53,19 @@ function run_test() {
// First, request to flush all permissions // First, request to flush all permissions
clear_imported_preferences_cache(); clear_imported_preferences_cache();
Services.prefs.setCharPref("xpinstall.whitelist.add.TEST2", "https://whitelist2.example.com"); Services.prefs.setCharPref("xpinstall.whitelist.add.TEST2", "whitelist2.example.com");
Services.obs.notifyObservers(null, "flush-pending-permissions", "install"); Services.obs.notifyObservers(null, "flush-pending-permissions", "install");
do_check_permission_prefs(preferences); do_check_permission_prefs(preferences);
// Then, request to flush just install permissions // Then, request to flush just install permissions
clear_imported_preferences_cache(); clear_imported_preferences_cache();
Services.prefs.setCharPref("xpinstall.whitelist.add.TEST3", "https://whitelist3.example.com"); Services.prefs.setCharPref("xpinstall.whitelist.add.TEST3", "whitelist3.example.com");
Services.obs.notifyObservers(null, "flush-pending-permissions", ""); Services.obs.notifyObservers(null, "flush-pending-permissions", "");
do_check_permission_prefs(preferences); do_check_permission_prefs(preferences);
// And a request to flush some other permissions sholdn't flush install permissions // And a request to flush some other permissions sholdn't flush install permissions
clear_imported_preferences_cache(); clear_imported_preferences_cache();
Services.prefs.setCharPref("xpinstall.whitelist.add.TEST4", "https://whitelist4.example.com"); Services.prefs.setCharPref("xpinstall.whitelist.add.TEST4", "whitelist4.example.com");
Services.obs.notifyObservers(null, "flush-pending-permissions", "lolcats"); Services.obs.notifyObservers(null, "flush-pending-permissions", "lolcats");
do_check_eq(Services.prefs.getCharPref("xpinstall.whitelist.add.TEST4"), "https://whitelist4.example.com"); do_check_eq(Services.prefs.getCharPref("xpinstall.whitelist.add.TEST4"), "whitelist4.example.com");
} }