зеркало из https://github.com/mozilla/gecko-dev.git
bug 746374 - differentiate click-to-play plugin permissions by type and vulnerability status r=jaws r=joshmoz
This commit is contained in:
Родитель
60dbdd1f7f
Коммит
df08f8d094
|
@ -238,7 +238,16 @@ var gPluginHandler = {
|
|||
},
|
||||
|
||||
canActivatePlugin: function PH_canActivatePlugin(objLoadingContent) {
|
||||
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
|
||||
let pluginPermission = Ci.nsIPermissionManager.UNKNOWN_ACTION;
|
||||
if (objLoadingContent.actualType) {
|
||||
let permissionString = pluginHost.getPermissionStringForType(objLoadingContent.actualType);
|
||||
let browser = gBrowser.getBrowserForDocument(objLoadingContent.ownerDocument.defaultView.top.document);
|
||||
pluginPermission = Services.perms.testPermission(browser.currentURI, permissionString);
|
||||
}
|
||||
|
||||
return !objLoadingContent.activated &&
|
||||
pluginPermission != Ci.nsIPermissionManager.DENY_ACTION &&
|
||||
objLoadingContent.pluginFallbackType !== Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW;
|
||||
},
|
||||
|
||||
|
@ -351,19 +360,26 @@ var gPluginHandler = {
|
|||
_handleClickToPlayEvent: function PH_handleClickToPlayEvent(aPlugin) {
|
||||
let doc = aPlugin.ownerDocument;
|
||||
let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document);
|
||||
let pluginsPermission = Services.perms.testPermission(browser.currentURI, "plugins");
|
||||
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
|
||||
let pluginPermission = Ci.nsIPermissionManager.UNKNOWN_ACTION;
|
||||
let objLoadingContent = aPlugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
if (objLoadingContent.actualType) {
|
||||
let permissionString = pluginHost.getPermissionStringForType(objLoadingContent.actualType);
|
||||
pluginPermission = Services.perms.testPermission(browser.currentURI, permissionString);
|
||||
}
|
||||
let overlay = doc.getAnonymousElementByAttribute(aPlugin, "class", "mainBox");
|
||||
|
||||
if (browser._clickToPlayPluginsActivated) {
|
||||
let objLoadingContent = aPlugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
objLoadingContent.playPlugin();
|
||||
return;
|
||||
} else if (pluginsPermission == Ci.nsIPermissionManager.DENY_ACTION) {
|
||||
if (pluginPermission == Ci.nsIPermissionManager.DENY_ACTION) {
|
||||
if (overlay)
|
||||
overlay.style.visibility = "hidden";
|
||||
return;
|
||||
}
|
||||
|
||||
if (browser._clickToPlayPluginsActivated) {
|
||||
objLoadingContent.playPlugin();
|
||||
return;
|
||||
}
|
||||
|
||||
if (overlay) {
|
||||
overlay.addEventListener("click", function(aEvent) {
|
||||
// Have to check that the target is not the link to update the plugin
|
||||
|
@ -417,10 +433,6 @@ var gPluginHandler = {
|
|||
|
||||
reshowClickToPlayNotification: function PH_reshowClickToPlayNotification() {
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
let pluginsPermission = Services.perms.testPermission(browser.currentURI, "plugins");
|
||||
if (pluginsPermission == Ci.nsIPermissionManager.DENY_ACTION)
|
||||
return;
|
||||
|
||||
if (gPluginHandler._pluginNeedsActivationExceptThese([]))
|
||||
gPluginHandler._showClickToPlayNotification(browser);
|
||||
},
|
||||
|
@ -513,7 +525,19 @@ var gPluginHandler = {
|
|||
}
|
||||
|
||||
return centerActions;
|
||||
},
|
||||
},
|
||||
|
||||
_setPermissionForPlugins: function PH_setPermissionForPlugins(aBrowser, aPermission, aPluginList) {
|
||||
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
|
||||
for (let plugin of aPluginList) {
|
||||
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
if (gPluginHandler.canActivatePlugin(objLoadingContent) &&
|
||||
objLoadingContent.actualType) {
|
||||
let permissionString = pluginHost.getPermissionStringForType(objLoadingContent.actualType);
|
||||
Services.perms.add(aBrowser.currentURI, permissionString, aPermission);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_showClickToPlayNotification: function PH_showClickToPlayNotification(aBrowser) {
|
||||
aBrowser._clickToPlayDoorhangerShown = true;
|
||||
|
@ -541,14 +565,14 @@ var gPluginHandler = {
|
|||
label: gNavigatorBundle.getString("activatePluginsMessage.always"),
|
||||
accessKey: gNavigatorBundle.getString("activatePluginsMessage.always.accesskey"),
|
||||
callback: function () {
|
||||
Services.perms.add(aBrowser.currentURI, "plugins", Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
gPluginHandler._setPermissionForPlugins(aBrowser, Ci.nsIPermissionManager.ALLOW_ACTION, cwu.plugins);
|
||||
gPluginHandler.activatePlugins(contentWindow);
|
||||
}
|
||||
},{
|
||||
label: gNavigatorBundle.getString("activatePluginsMessage.never"),
|
||||
accessKey: gNavigatorBundle.getString("activatePluginsMessage.never.accesskey"),
|
||||
callback: function () {
|
||||
Services.perms.add(aBrowser.currentURI, "plugins", Ci.nsIPermissionManager.DENY_ACTION);
|
||||
gPluginHandler._setPermissionForPlugins(aBrowser, Ci.nsIPermissionManager.DENY_ACTION, cwu.plugins);
|
||||
let notification = PopupNotifications.getNotification("click-to-play-plugins", aBrowser);
|
||||
if (notification)
|
||||
notification.remove();
|
||||
|
@ -567,7 +591,9 @@ var gPluginHandler = {
|
|||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
for (let plugin of cwu.plugins) {
|
||||
let overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
|
||||
overlay.style.visibility = "hidden";
|
||||
// for already activated plugins, there will be no overlay
|
||||
if (overlay)
|
||||
overlay.style.visibility = "hidden";
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -402,9 +402,26 @@ function test12c() {
|
|||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(objLoadingContent.activated, "Test 12c, Plugin should be activated");
|
||||
|
||||
prepareTest(test12d, gHttpTestRoot + "plugin_two_types.html");
|
||||
}
|
||||
|
||||
// Test that the "Always" permission, when set for just the Test plugin,
|
||||
// does not also allow the Second Test plugin.
|
||||
function test12d() {
|
||||
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
|
||||
ok(popupNotification, "Test 12d, Should have a click-to-play notification");
|
||||
var test = gTestBrowser.contentDocument.getElementById("test");
|
||||
var secondtestA = gTestBrowser.contentDocument.getElementById("secondtestA");
|
||||
var secondtestB = gTestBrowser.contentDocument.getElementById("secondtestB");
|
||||
var objLoadingContent = test.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(objLoadingContent.activated, "Test 12d, Test plugin should be activated");
|
||||
var objLoadingContent = secondtestA.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(!objLoadingContent.activated, "Test 12d, Second Test plugin (A) should not be activated");
|
||||
var objLoadingContent = secondtestB.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(!objLoadingContent.activated, "Test 12d, Second Test plugin (B) should not be activated");
|
||||
|
||||
Services.perms.removeAll();
|
||||
gNextTest = test13a;
|
||||
gTestBrowser.reload();
|
||||
prepareTest(test13a, gHttpTestRoot + "plugin_clickToPlayDeny.html");
|
||||
}
|
||||
|
||||
// Tests that the "Deny Always" permission works for click-to-play plugins (part 1/3)
|
||||
|
@ -444,6 +461,55 @@ function test13c() {
|
|||
var overlay = gTestBrowser.contentDocument.getAnonymousElementByAttribute(plugin, "class", "mainBox");
|
||||
ok(overlay.style.visibility == "hidden", "Test 13c, Plugin should not have visible overlay");
|
||||
|
||||
prepareTest(test13d, gHttpTestRoot + "plugin_two_types.html");
|
||||
}
|
||||
|
||||
// Test that the "Deny Always" permission, when set for just the Test plugin,
|
||||
// does not also block the Second Test plugin (i.e. it gets an overlay and
|
||||
// there's a notification and everything).
|
||||
function test13d() {
|
||||
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
|
||||
ok(popupNotification, "Test 13d, Should have a click-to-play notification");
|
||||
|
||||
var test = gTestBrowser.contentDocument.getElementById("test");
|
||||
var objLoadingContent = test.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
var overlay = gTestBrowser.contentDocument.getAnonymousElementByAttribute(test, "class", "mainBox");
|
||||
ok(overlay.style.visibility == "hidden", "Test 13d, Test plugin should not have visible overlay");
|
||||
ok(!objLoadingContent.activated, "Test 13d, Test plugin should not be activated");
|
||||
|
||||
var secondtestA = gTestBrowser.contentDocument.getElementById("secondtestA");
|
||||
var objLoadingContent = secondtestA.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
var overlay = gTestBrowser.contentDocument.getAnonymousElementByAttribute(secondtestA, "class", "mainBox");
|
||||
ok(overlay.style.visibility != "hidden", "Test 13d, Test plugin should have visible overlay");
|
||||
ok(!objLoadingContent.activated, "Test 13d, Second Test plugin (A) should not be activated");
|
||||
|
||||
var secondtestB = gTestBrowser.contentDocument.getElementById("secondtestB");
|
||||
var objLoadingContent = secondtestB.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
var overlay = gTestBrowser.contentDocument.getAnonymousElementByAttribute(secondtestB, "class", "mainBox");
|
||||
ok(overlay.style.visibility != "hidden", "Test 13d, Test plugin should have visible overlay");
|
||||
ok(!objLoadingContent.activated, "Test 13d, Second Test plugin (B) should not be activated");
|
||||
|
||||
var condition = function() objLoadingContent.activated;
|
||||
// "click" "Activate All Plugins"
|
||||
popupNotification.mainAction.callback();
|
||||
waitForCondition(condition, test13e, "Test 13d, Waited too long for plugin to activate");
|
||||
}
|
||||
|
||||
// Test that clicking "Activate All Plugins" won't activate plugins that
|
||||
// have previously been "Deny Always"-ed.
|
||||
function test13e() {
|
||||
var test = gTestBrowser.contentDocument.getElementById("test");
|
||||
var objLoadingContent = test.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(!objLoadingContent.activated, "Test 13e, Test plugin should not be activated");
|
||||
|
||||
var secondtestA = gTestBrowser.contentDocument.getElementById("secondtestA");
|
||||
var objLoadingContent = secondtestA.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(objLoadingContent.activated, "Test 13e, Second Test plugin (A) should be activated");
|
||||
|
||||
var secondtestB = gTestBrowser.contentDocument.getElementById("secondtestB");
|
||||
var objLoadingContent = secondtestB.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(objLoadingContent.activated, "Test 13e, Second Test plugin (B) should be activated");
|
||||
|
||||
Services.perms.removeAll();
|
||||
Services.prefs.setBoolPref("plugins.click_to_play", false);
|
||||
prepareTest(test14, gTestRoot + "plugin_test2.html");
|
||||
|
@ -932,5 +998,123 @@ function test23() {
|
|||
is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, "Test 23, Plugin should be click-to-play");
|
||||
ok(!pluginNode.activated, "Test 23, plugin node should not be activated");
|
||||
|
||||
prepareTest(test24a, gHttpTestRoot + "plugin_test.html");
|
||||
}
|
||||
|
||||
// Test that "always allow"-ing a plugin will not allow it when it becomes
|
||||
// blocklisted.
|
||||
function test24a() {
|
||||
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
|
||||
ok(notification, "Test 24a, Should have a click-to-play notification");
|
||||
var plugin = gTestBrowser.contentDocument.getElementById("test");
|
||||
ok(plugin, "Test 24a, Found plugin in page");
|
||||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, "Test 24a, Plugin should be click-to-play");
|
||||
ok(!objLoadingContent.activated, "Test 24a, plugin should not be activated");
|
||||
|
||||
// simulate "always allow"
|
||||
notification.secondaryActions[0].callback();
|
||||
prepareTest(test24b, gHttpTestRoot + "plugin_test.html");
|
||||
}
|
||||
|
||||
// did the "always allow" work as intended?
|
||||
function test24b() {
|
||||
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
|
||||
ok(!notification, "Test 24b, Should not have a click-to-play notification");
|
||||
var plugin = gTestBrowser.contentDocument.getElementById("test");
|
||||
ok(plugin, "Test 24b, Found plugin in page");
|
||||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(objLoadingContent.activated, "Test 24b, plugin should be activated");
|
||||
setAndUpdateBlocklist(gHttpTestRoot + "blockPluginVulnerableUpdatable.xml",
|
||||
function() {
|
||||
prepareTest(test24c, gHttpTestRoot + "plugin_test.html");
|
||||
});
|
||||
}
|
||||
|
||||
// the plugin is now blocklisted, so it should not automatically load
|
||||
function test24c() {
|
||||
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
|
||||
ok(notification, "Test 24c, Should have a click-to-play notification");
|
||||
var plugin = gTestBrowser.contentDocument.getElementById("test");
|
||||
ok(plugin, "Test 24c, Found plugin in page");
|
||||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE, "Test 24c, Plugin should be vulnerable/updatable");
|
||||
ok(!objLoadingContent.activated, "Test 24c, plugin should not be activated");
|
||||
|
||||
// simulate "always allow"
|
||||
notification.secondaryActions[0].callback();
|
||||
prepareTest(test24d, gHttpTestRoot + "plugin_test.html");
|
||||
}
|
||||
|
||||
// We should still be able to always allow a plugin after we've seen that it's
|
||||
// blocklisted.
|
||||
function test24d() {
|
||||
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
|
||||
ok(!notification, "Test 24d, Should not have a click-to-play notification");
|
||||
var plugin = gTestBrowser.contentDocument.getElementById("test");
|
||||
ok(plugin, "Test 24d, Found plugin in page");
|
||||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(objLoadingContent.activated, "Test 24d, plugin should be activated");
|
||||
|
||||
Services.perms.removeAll();
|
||||
resetBlocklist(function () {
|
||||
prepareTest(test25a, gHttpTestRoot + "plugin_test.html");
|
||||
});
|
||||
}
|
||||
|
||||
// Test that clicking "always allow" or "always deny" doesn't affect plugins
|
||||
// that already have permission given to them
|
||||
function test25a() {
|
||||
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
|
||||
ok(notification, "Test 25a, Should have a click-to-play notification");
|
||||
var plugin = gTestBrowser.contentDocument.getElementById("test");
|
||||
ok(plugin, "Test 25a, Found plugin in page");
|
||||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(!objLoadingContent.activated, "Test 25a, plugin should not be activated");
|
||||
|
||||
// simulate "always allow"
|
||||
notification.secondaryActions[0].callback();
|
||||
prepareTest(test25b, gHttpTestRoot + "plugin_two_types.html");
|
||||
}
|
||||
|
||||
function test25b() {
|
||||
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
|
||||
ok(notification, "Test 25b, Should have a click-to-play notification");
|
||||
|
||||
var test = gTestBrowser.contentDocument.getElementById("test");
|
||||
ok(test, "Test 25b, Found test plugin in page");
|
||||
var objLoadingContent = test.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(objLoadingContent.activated, "Test 25b, test plugin should be activated");
|
||||
|
||||
var secondtest = gTestBrowser.contentDocument.getElementById("secondtestA");
|
||||
ok(secondtest, "Test 25b, Found second test plugin in page");
|
||||
var objLoadingContent = secondtest.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(!objLoadingContent.activated, "Test 25b, second test plugin should not be activated");
|
||||
|
||||
// simulate "always deny"
|
||||
notification.secondaryActions[1].callback();
|
||||
prepareTest(test25c, gHttpTestRoot + "plugin_two_types.html");
|
||||
}
|
||||
|
||||
// we should have one plugin allowed to activate and the other plugin(s) denied
|
||||
// (so it should have an invisible overlay)
|
||||
function test25c() {
|
||||
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
|
||||
ok(!notification, "Test 25c, Should not have a click-to-play notification");
|
||||
|
||||
var test = gTestBrowser.contentDocument.getElementById("test");
|
||||
ok(test, "Test 25c, Found test plugin in page");
|
||||
var objLoadingContent = test.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(objLoadingContent.activated, "Test 25c, test plugin should be activated");
|
||||
|
||||
var secondtest = gTestBrowser.contentDocument.getElementById("secondtestA");
|
||||
ok(secondtest, "Test 25c, Found second test plugin in page");
|
||||
var objLoadingContent = secondtest.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(!objLoadingContent.activated, "Test 25c, second test plugin should not be activated");
|
||||
var overlay = gTestBrowser.contentDocument.getAnonymousElementByAttribute(secondtest, "class", "mainBox");
|
||||
ok(overlay.style.visibility == "hidden", "Test 25c, second test plugin should not have visible overlay");
|
||||
|
||||
Services.perms.removeAll();
|
||||
|
||||
finishTest();
|
||||
}
|
||||
|
|
|
@ -2561,9 +2561,12 @@ nsObjectLoadingContent::ShouldPlay(FallbackType &aReason)
|
|||
// the system principal, i.e. in chrome pages. That way the click-to-play
|
||||
// code here wouldn't matter at all. Bug 775301 is tracking this.
|
||||
if (!nsContentUtils::IsSystemPrincipal(topDoc->NodePrincipal())) {
|
||||
nsAutoCString permissionString;
|
||||
rv = pluginHost->GetPermissionStringForType(mContentType, permissionString);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
uint32_t permission;
|
||||
rv = permissionManager->TestPermissionFromPrincipal(topDoc->NodePrincipal(),
|
||||
"plugins",
|
||||
permissionString.Data(),
|
||||
&permission);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
allowPerm = permission == nsIPermissionManager::ALLOW_ACTION;
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
"@mozilla.org/plugin/host;1"
|
||||
%}
|
||||
|
||||
[scriptable, uuid(d70af999-cb1f-4429-b85e-f18cdbabc43c)]
|
||||
[scriptable, uuid(3ac8fe33-c38c-4123-b2f0-0e8a2824b9c5)]
|
||||
interface nsIPluginHost : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -82,6 +82,8 @@ interface nsIPluginHost : nsISupports
|
|||
|
||||
void unregisterPlayPreviewMimeType(in AUTF8String mimeType);
|
||||
|
||||
ACString getPermissionStringForType(in AUTF8String mimeType);
|
||||
|
||||
bool isPluginClickToPlayForType(in AUTF8String mimeType);
|
||||
};
|
||||
|
||||
|
|
|
@ -1347,6 +1347,31 @@ nsPluginHost::GetBlocklistStateForType(const char *aMimeType, uint32_t *aState)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginHost::GetPermissionStringForType(const nsACString &aMimeType, nsACString &aPermissionString)
|
||||
{
|
||||
aPermissionString.Truncate();
|
||||
uint32_t blocklistState;
|
||||
nsresult rv = GetBlocklistStateForType(aMimeType.Data(), &blocklistState);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsPluginTag *tag = FindPluginForType(aMimeType.Data(), true);
|
||||
if (!tag) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (blocklistState == nsIBlocklistService::STATE_VULNERABLE_UPDATE_AVAILABLE ||
|
||||
blocklistState == nsIBlocklistService::STATE_VULNERABLE_NO_UPDATE) {
|
||||
aPermissionString.AssignLiteral("plugin-vulnerable:");
|
||||
}
|
||||
else {
|
||||
aPermissionString.AssignLiteral("plugin:");
|
||||
}
|
||||
|
||||
aPermissionString.Append(tag->mFileName);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// check comma delimitered extensions
|
||||
static int CompareExtensions(const char *aExtensionList, const char *aExtension)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче