2017-01-31 21:31:55 +01:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
(function(){
|
|
|
|
"use strict";
|
2017-07-07 08:49:12 +02:00
|
|
|
|
2017-11-07 00:36:44 +01:00
|
|
|
const settings = require("./settings");
|
2017-12-04 00:26:26 +01:00
|
|
|
const {preIntercept: intercept} = require("./intercept.js");
|
2017-01-31 21:31:55 +01:00
|
|
|
const {ask} = require("./askForPermission.js");
|
2017-09-23 23:37:46 +02:00
|
|
|
const lists = require("./lists.js");
|
2017-01-31 21:31:55 +01:00
|
|
|
const {check: originalCheck, checkStack: originalCheckStack} = require("./check.js");
|
2017-10-07 23:26:04 +02:00
|
|
|
const getWrapped = require("sdk/getWrapped");
|
2017-01-31 21:31:55 +01:00
|
|
|
|
2017-09-23 23:37:46 +02:00
|
|
|
const logging = require("./logging");
|
|
|
|
const {error, warning, message, notice, verbose, setPrefix: setLogPrefix} = logging;
|
2017-07-27 19:14:04 +02:00
|
|
|
setLogPrefix("frame script");
|
|
|
|
|
2017-01-31 21:31:55 +01:00
|
|
|
// Variable to "unload" the script
|
|
|
|
var enabled = true;
|
|
|
|
|
2017-07-27 19:14:04 +02:00
|
|
|
message("starting", location.href);
|
2017-01-31 21:31:55 +01:00
|
|
|
|
|
|
|
function check(message){
|
|
|
|
if (enabled){
|
|
|
|
return originalCheck(message);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return {type: [], mode: "allow"};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function checkStack(stack){
|
|
|
|
if (enabled){
|
|
|
|
return originalCheckStack(stack);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function askWrapper(data){
|
|
|
|
return ask(data, {
|
2017-10-06 16:06:31 +02:00
|
|
|
_: browser.i18n.getMessage,
|
2017-01-31 21:31:55 +01:00
|
|
|
prefs
|
|
|
|
});
|
|
|
|
}
|
2017-07-16 00:25:19 +02:00
|
|
|
|
2017-07-27 19:14:04 +02:00
|
|
|
message("open port to background script");
|
2017-06-29 07:21:36 +02:00
|
|
|
var port = browser.runtime.connect();
|
2017-11-14 23:57:44 +01:00
|
|
|
if (window === window.top){
|
|
|
|
message("Is top level window -> tab had navigation -> clear page action");
|
|
|
|
port.postMessage({"canvasBlocker-clear-page-action": true});
|
|
|
|
}
|
2017-06-29 07:21:36 +02:00
|
|
|
var tabId;
|
|
|
|
port.onMessage.addListener(function(data){
|
2017-11-07 00:36:44 +01:00
|
|
|
message("Got data from port", data);
|
2017-06-29 07:21:36 +02:00
|
|
|
if (data.hasOwnProperty("tabId")){
|
2017-07-27 19:14:04 +02:00
|
|
|
notice("my tab id is", data.tabId);
|
2017-06-29 07:21:36 +02:00
|
|
|
tabId = data.tabId;
|
|
|
|
}
|
2018-07-28 14:13:14 +02:00
|
|
|
const persistentRndName = "persistent" + (browser.extension.inIncognitoContext? "Incognito": "") + "Rnd";
|
|
|
|
if (data.hasOwnProperty(persistentRndName)){
|
|
|
|
const persistentRndValue = data[persistentRndName];
|
|
|
|
notice("got persistent random data", persistentRndValue);
|
2017-09-23 23:37:46 +02:00
|
|
|
const {persistent: persistentRnd} = require("./randomSupplies.js");
|
2018-07-28 14:13:14 +02:00
|
|
|
Object.keys(persistentRndValue).forEach(function(domain){
|
|
|
|
verbose("random data for", domain, persistentRndValue[domain]);
|
|
|
|
persistentRnd.setDomainRnd(domain, persistentRndValue[domain]);
|
2017-09-23 23:37:46 +02:00
|
|
|
});
|
|
|
|
}
|
2017-06-29 07:21:36 +02:00
|
|
|
});
|
|
|
|
var notifications = [];
|
2018-09-11 23:54:59 +02:00
|
|
|
var notificationCounter = {};
|
2018-09-16 12:15:04 +02:00
|
|
|
var sentAPIs = {};
|
2017-01-31 21:31:55 +01:00
|
|
|
function notify(data){
|
2018-09-09 00:15:21 +02:00
|
|
|
if (!settings.ignoredAPIs[data.api]){
|
2018-09-11 23:54:59 +02:00
|
|
|
if (settings.storeNotificationData){
|
|
|
|
notifications.push(data);
|
|
|
|
}
|
|
|
|
notificationCounter[data.messageId] = (notificationCounter[data.messageId] || 0) + 1;
|
2018-09-16 12:15:04 +02:00
|
|
|
if (!sentAPIs[data.api]){
|
|
|
|
sentAPIs[data.api] = true;
|
|
|
|
port.postMessage({"canvasBlocker-notify": data});
|
|
|
|
}
|
2018-09-09 00:15:21 +02:00
|
|
|
}
|
2017-01-31 21:31:55 +01:00
|
|
|
}
|
|
|
|
|
2017-12-03 23:47:49 +01:00
|
|
|
function prefs(...args){
|
|
|
|
return settings.get(...args);
|
2017-01-31 21:31:55 +01:00
|
|
|
}
|
|
|
|
|
2017-06-25 22:33:12 +02:00
|
|
|
|
|
|
|
var interceptedWindows = new WeakMap();
|
|
|
|
function interceptWindow(window){
|
2017-07-18 16:14:03 +02:00
|
|
|
try {
|
|
|
|
var href = window.location.href;
|
|
|
|
}
|
|
|
|
catch (e){
|
|
|
|
// we are unable to read the location due to SOP
|
|
|
|
// therefore we also can not intercept anything.
|
2017-09-23 23:40:57 +02:00
|
|
|
warning("NOT intercepting window due to SOP", window);
|
2017-07-18 16:14:03 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-10-10 21:11:50 +02:00
|
|
|
if (!enabled || interceptedWindows.get(getWrapped(window))){
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-07-27 19:14:04 +02:00
|
|
|
message("intercepting window", window);
|
2017-06-25 22:33:12 +02:00
|
|
|
intercept(
|
|
|
|
{subject: window},
|
|
|
|
{check, checkStack, ask: askWrapper, notify, prefs}
|
|
|
|
);
|
2017-07-27 19:14:04 +02:00
|
|
|
message("prepare to intercept (i)frames.");
|
2017-10-07 23:26:04 +02:00
|
|
|
|
2017-06-25 22:33:12 +02:00
|
|
|
[window.HTMLIFrameElement, window.HTMLFrameElement].forEach(function(constructor){
|
|
|
|
var oldContentWindowGetter = constructor.prototype.__lookupGetter__("contentWindow");
|
|
|
|
Object.defineProperty(
|
2017-10-07 23:26:04 +02:00
|
|
|
getWrapped(constructor.prototype),
|
2017-06-25 22:33:12 +02:00
|
|
|
"contentWindow",
|
|
|
|
{
|
|
|
|
enumerable: true,
|
2018-08-22 22:16:49 +02:00
|
|
|
configurable: true,
|
2017-06-25 22:33:12 +02:00
|
|
|
get: exportFunction(function(){
|
|
|
|
var window = oldContentWindowGetter.call(this);
|
2017-10-10 21:11:50 +02:00
|
|
|
if (window){
|
|
|
|
interceptWindow(window);
|
|
|
|
}
|
2017-06-25 22:33:12 +02:00
|
|
|
return window;
|
|
|
|
}, window)
|
|
|
|
}
|
|
|
|
);
|
|
|
|
var oldContentDocumentGetter = constructor.prototype.__lookupGetter__("contentDocument");
|
|
|
|
Object.defineProperty(
|
2017-10-07 23:26:04 +02:00
|
|
|
getWrapped(constructor.prototype),
|
2017-06-25 22:33:12 +02:00
|
|
|
"contentDocument",
|
|
|
|
{
|
|
|
|
enumerable: true,
|
2018-08-22 22:16:49 +02:00
|
|
|
configurable: true,
|
2017-06-25 22:33:12 +02:00
|
|
|
get: exportFunction(function(){
|
|
|
|
var document = oldContentDocumentGetter.call(this);
|
2017-10-10 21:11:50 +02:00
|
|
|
if (document){
|
|
|
|
interceptWindow(document.defaultView);
|
|
|
|
}
|
2017-06-25 22:33:12 +02:00
|
|
|
return document;
|
|
|
|
}, window)
|
|
|
|
}
|
|
|
|
);
|
2017-01-31 21:31:55 +01:00
|
|
|
});
|
2017-06-25 22:33:12 +02:00
|
|
|
|
2017-10-10 21:11:50 +02:00
|
|
|
interceptedWindows.set(getWrapped(window), true);
|
2017-06-25 22:33:12 +02:00
|
|
|
return true;
|
2017-10-03 15:35:31 +02:00
|
|
|
}
|
2017-06-25 22:33:12 +02:00
|
|
|
|
2017-07-27 19:14:04 +02:00
|
|
|
message("register listener for messages from background script");
|
2017-06-25 22:33:12 +02:00
|
|
|
browser.runtime.onMessage.addListener(function(data){
|
|
|
|
if (data["canvasBlocker-unload"]){
|
|
|
|
enabled = false;
|
|
|
|
}
|
2017-10-06 16:06:31 +02:00
|
|
|
if (
|
|
|
|
data.hasOwnProperty("canvasBlocker-sendNotifications") &&
|
|
|
|
data["canvasBlocker-sendNotifications"] === tabId
|
|
|
|
){
|
2017-07-27 19:14:04 +02:00
|
|
|
notice("sending notifications:", notifications);
|
2017-06-29 07:21:36 +02:00
|
|
|
browser.runtime.sendMessage({
|
|
|
|
sender: tabId,
|
2018-09-11 23:54:59 +02:00
|
|
|
url: window.location.href,
|
|
|
|
"canvasBlocker-notificationCounter": notificationCounter,
|
2017-06-29 07:21:36 +02:00
|
|
|
"canvasBlocker-notifications": notifications
|
|
|
|
});
|
2017-07-27 19:14:04 +02:00
|
|
|
notice("notifications sent");
|
2017-06-29 07:21:36 +02:00
|
|
|
}
|
2017-01-31 21:31:55 +01:00
|
|
|
});
|
2017-11-14 01:04:20 +01:00
|
|
|
|
2017-12-04 00:26:26 +01:00
|
|
|
interceptWindow(window);
|
2017-01-31 21:31:55 +01:00
|
|
|
}());
|