[tbb-commits] [torbutton] branch main updated: Bug 40012: Linted torbutton
gitolite role
git at cupani.torproject.org
Thu Aug 25 16:29:56 UTC 2022
This is an automated email from the git hooks/post-receive script.
pierov pushed a commit to branch main
in repository torbutton.
The following commit(s) were added to refs/heads/main by this push:
new 9f2e434a Bug 40012: Linted torbutton
9f2e434a is described below
commit 9f2e434a7f09d2f53c529e7293bf715c4a6b71e6
Author: Pier Angelo Vendrame <pierov at torproject.org>
AuthorDate: Wed Aug 24 16:28:30 2022 +0200
Bug 40012: Linted torbutton
---
chrome/content/aboutTor/aboutTor-content.js | 64 +-
chrome/content/preferences-mobile.js | 49 +-
chrome/content/tor-circuit-display.js | 907 +++++++++-------
chrome/content/torbutton.js | 1561 ++++++++++++++-------------
components/domain-isolator.js | 98 +-
components/dragDropFilter.js | 39 +-
components/external-app-blocker.js | 75 +-
components/startup-observer.js | 270 ++---
components/torCheckService.js | 119 +-
components/torbutton-logger.js | 201 ++--
modules/tor-control-port.js | 457 ++++----
modules/utils.js | 238 ++--
12 files changed, 2217 insertions(+), 1861 deletions(-)
diff --git a/chrome/content/aboutTor/aboutTor-content.js b/chrome/content/aboutTor/aboutTor-content.js
index 601b817c..55bf4413 100644
--- a/chrome/content/aboutTor/aboutTor-content.js
+++ b/chrome/content/aboutTor/aboutTor-content.js
@@ -14,9 +14,14 @@
* AboutTor:ChromeData privileged data chrome -> content
*/
+/* globals content, addMessageListener, sendAsyncMessage,
+ removeMessageListener */
+
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-let { bindPrefAndInit, show_torbrowser_manual } = ChromeUtils.import("resource://torbutton/modules/utils.js", {});
+const { bindPrefAndInit, show_torbrowser_manual } = ChromeUtils.import(
+ "resource://torbutton/modules/utils.js"
+);
var AboutTorListener = {
kAboutTorLoadedMessage: "AboutTor:Loaded",
@@ -26,13 +31,14 @@ var AboutTorListener = {
return content.document.documentURI.toLowerCase() == "about:tor";
},
- init: function(aChromeGlobal) {
+ init(aChromeGlobal) {
aChromeGlobal.addEventListener("AboutTorLoad", this, false, true);
},
- handleEvent: function(aEvent) {
- if (!this.isAboutTor)
+ handleEvent(aEvent) {
+ if (!this.isAboutTor) {
return;
+ }
switch (aEvent.type) {
case "AboutTorLoad":
@@ -44,9 +50,10 @@ var AboutTorListener = {
}
},
- receiveMessage: function(aMessage) {
- if (!this.isAboutTor)
+ receiveMessage(aMessage) {
+ if (!this.isAboutTor) {
return;
+ }
switch (aMessage.name) {
case this.kAboutTorChromeDataMessage:
@@ -55,7 +62,7 @@ var AboutTorListener = {
}
},
- onPageLoad: function() {
+ onPageLoad() {
// Arrange to update localized text and links.
bindPrefAndInit("intl.locale.requested", () => {
const aNewVal = Services.locale.requestedLocale;
@@ -72,48 +79,53 @@ var AboutTorListener = {
sendAsyncMessage(this.kAboutTorLoadedMessage);
},
- onPageHide: function() {
+ onPageHide() {
removeEventListener("resize", this, false);
removeEventListener("pagehide", this, false);
removeMessageListener(this.kAboutTorChromeDataMessage, this);
},
- onChromeDataUpdate: function(aData) {
+ onChromeDataUpdate(aData) {
let body = content.document.body;
// Update status: tor on/off, Tor Browser manual shown.
- if (aData.torOn)
+ if (aData.torOn) {
body.setAttribute("toron", "yes");
- else
+ } else {
body.removeAttribute("toron");
+ }
- if (show_torbrowser_manual())
+ if (show_torbrowser_manual()) {
body.setAttribute("showmanual", "yes");
- else
+ } else {
body.removeAttribute("showmanual");
+ }
- if (aData.updateChannel)
+ if (aData.updateChannel) {
body.setAttribute("updatechannel", aData.updateChannel);
- else
+ } else {
body.removeAttribute("updatechannel");
+ }
if (aData.hasBeenUpdated) {
body.setAttribute("hasbeenupdated", "yes");
- content.document.getElementById("update-infolink").setAttribute("href",
- aData.updateMoreInfoURL);
+ content.document
+ .getElementById("update-infolink")
+ .setAttribute("href", aData.updateMoreInfoURL);
}
- if (aData.mobile)
+ if (aData.mobile) {
body.setAttribute("mobile", "yes");
+ }
// Setting body.initialized="yes" displays the body.
body.setAttribute("initialized", "yes");
},
- onLocaleChange: function(aLocale) {
+ onLocaleChange(aLocale) {
// Set localized "Get Involved" link.
content.document.getElementById("getInvolvedLink").href =
- "https://community.torproject.org/" + aLocale;
+ "https://community.torproject.org/" + aLocale;
// Display the Tor Browser product name and version.
try {
@@ -123,12 +135,14 @@ var AboutTorListener = {
let tbbVersion = Services.prefs.getCharPref("torbrowser.version");
let elem = content.document.getElementById("torbrowser-version");
- while (elem.firstChild)
- elem.removeChild(elem.firstChild);
- elem.appendChild(content.document.createTextNode(productName + ' '
- + tbbVersion));
+ while (elem.firstChild) {
+ elem.firstChild.remove();
+ }
+ elem.appendChild(
+ content.document.createTextNode(productName + " " + tbbVersion)
+ );
} catch (e) {}
- }
+ },
};
AboutTorListener.init(this);
diff --git a/chrome/content/preferences-mobile.js b/chrome/content/preferences-mobile.js
index fa79dce8..92564e90 100644
--- a/chrome/content/preferences-mobile.js
+++ b/chrome/content/preferences-mobile.js
@@ -2,26 +2,30 @@
// Utilities
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-const { getBoolPref, getIntPref, setBoolPref, setIntPref, getCharPref }
- = Services.prefs;
+const {
+ getBoolPref,
+ getIntPref,
+ setBoolPref,
+ setIntPref,
+ getCharPref,
+} = Services.prefs;
-let { getLocale, show_torbrowser_manual } =
- ChromeUtils.import("resource://torbutton/modules/utils.js", {});
+let { getLocale, show_torbrowser_manual } = ChromeUtils.import(
+ "resource://torbutton/modules/utils.js"
+);
// Description elements have the follow names.
-const descNames =
- [, "desc_standard", "desc_safer", "desc_safest"];
+const descNames = ["", "desc_standard", "desc_safer", "desc_safest"];
// "Learn-more"-elements have the follow names.
-const linkNames =
- [, "link_standard", "link_safer", "link_safest"];
+const linkNames = ["", "link_standard", "link_safer", "link_safest"];
// A single `state` object that reflects the user settings in this UI.
-let state = { slider : 0, custom : false};
+let state = { slider: 0, custom: false };
// Utility functions to convert between the legacy 4-value pref index
// and the 3-valued security slider.
-let sliderPositionToPrefSetting = pos => [, 4, 2, 1][pos];
-let prefSettingToSliderPosition = pref => [, 3, 2, 2, 1][pref];
+let sliderPositionToPrefSetting = pos => [0, 4, 2, 1][pos];
+let prefSettingToSliderPosition = pref => [0, 3, 2, 2, 1][pref];
// Set the desired slider value and update UI.
function torbutton_set_slider(sliderValue) {
@@ -31,9 +35,9 @@ function torbutton_set_slider(sliderValue) {
let descs = descNames.map(name => document.getElementById(name));
descs.forEach((desc, i) => {
if (state.slider !== i) {
- desc.style.display = 'none';
+ desc.style.display = "none";
} else {
- desc.style.display = 'block';
+ desc.style.display = "block";
}
});
torbutton_save_security_settings();
@@ -42,15 +46,20 @@ function torbutton_set_slider(sliderValue) {
// Read prefs 'extensions.torbutton.security_slider' and
// 'extensions.torbutton.security_custom', and initialize the UI.
function torbutton_init_security_ui() {
- torbutton_set_slider(prefSettingToSliderPosition(
- getIntPref("extensions.torbutton.security_slider")));
+ torbutton_set_slider(
+ prefSettingToSliderPosition(
+ getIntPref("extensions.torbutton.security_slider")
+ )
+ );
torbutton_set_learn_more_links();
}
// Write the two prefs from the current settings.
function torbutton_save_security_settings() {
- setIntPref("extensions.torbutton.security_slider",
- sliderPositionToPrefSetting(state.slider));
+ setIntPref(
+ "extensions.torbutton.security_slider",
+ sliderPositionToPrefSetting(state.slider)
+ );
setBoolPref("extensions.torbutton.security_custom", state.custom);
}
@@ -59,15 +68,15 @@ function torbutton_save_security_settings() {
// let's show the "Learn more"-link, otherwise hide it.
function torbutton_set_learn_more_links() {
let show_manual = show_torbrowser_manual();
- let locale = ""
+ let locale = "";
if (show_manual) {
locale = getLocale();
}
let links = linkNames.map(name => document.getElementById(name));
links.forEach(link => {
if (show_manual && locale != "") {
- link.href= "https:/tb-manual.torproject.org/" + locale +
- "/security-slider.html";
+ link.href =
+ "https:/tb-manual.torproject.org/" + locale + "/security-slider.html";
link.hidden = false;
} else {
link.hidden = true;
diff --git a/chrome/content/tor-circuit-display.js b/chrome/content/tor-circuit-display.js
index 14e3da5b..e4b5ceea 100644
--- a/chrome/content/tor-circuit-display.js
+++ b/chrome/content/tor-circuit-display.js
@@ -21,28 +21,38 @@
// a previous call to configureControlPortModule(), and binds to a named
// bool pref whose value determines whether the circuit display is enabled
// or disabled.
-let createTorCircuitDisplay = (function () {
-
-"use strict";
-
-// Mozilla utilities
-const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-// Import the controller code.
-let { wait_for_controller } = ChromeUtils.import("resource://torbutton/modules/tor-control-port.js", {});
-
-// Utility functions
-let { bindPrefAndInit, observe, getLocale, getDomainForBrowser, torbutton_get_property_string } = ChromeUtils.import("resource://torbutton/modules/utils.js", {});
-
-// Make the TorButton logger available.
-let logger = Cc["@torproject.org/torbutton-logger;1"]
- .getService(Ci.nsISupports).wrappedJSObject;
-
-// ## Circuit/stream credentials and node monitoring
-
-// A mutable map that stores the current nodes for each
-// SOCKS username/password pair.
-let credentialsToNodeDataMap = new Map(),
+let createTorCircuitDisplay = (function() {
+ "use strict";
+
+ // Mozilla utilities
+ const { Services } = ChromeUtils.import(
+ "resource://gre/modules/Services.jsm"
+ );
+
+ // Import the controller code.
+ const { wait_for_controller } = ChromeUtils.import(
+ "resource://torbutton/modules/tor-control-port.js"
+ );
+
+ // Utility functions
+ let {
+ bindPrefAndInit,
+ observe,
+ getLocale,
+ getDomainForBrowser,
+ torbutton_get_property_string,
+ } = ChromeUtils.import("resource://torbutton/modules/utils.js");
+
+ // Make the TorButton logger available.
+ let logger = Cc["@torproject.org/torbutton-logger;1"].getService(
+ Ci.nsISupports
+ ).wrappedJSObject;
+
+ // ## Circuit/stream credentials and node monitoring
+
+ // A mutable map that stores the current nodes for each
+ // SOCKS username/password pair.
+ let credentialsToNodeDataMap = new Map(),
// A mutable map that reports `true` for IDs of "mature" circuits
// (those that have conveyed a stream).
knownCircuitIDs = new Map(),
@@ -50,424 +60,477 @@ let credentialsToNodeDataMap = new Map(),
// latest channels for each browser + domain.
browserToCredentialsMap = new Map();
-// __trimQuotes(s)__.
-// Removes quotation marks around a quoted string.
-let trimQuotes = s => s ? s.match(/^"(.*)"$/)[1] : undefined;
-
-// __getBridge(id)__.
-// Gets the bridge parameters for a given node ID. If the node
-// is not currently used as a bridge, returns null.
-let getBridge = async function (controller, id) {
- let bridges = await controller.getConf("bridge");
- if (bridges) {
- for (let bridge of bridges) {
- if (bridge.ID && bridge.ID.toUpperCase() === id.toUpperCase()) {
- return bridge;
+ // __trimQuotes(s)__.
+ // Removes quotation marks around a quoted string.
+ let trimQuotes = s => (s ? s.match(/^"(.*)"$/)[1] : undefined);
+
+ // __getBridge(id)__.
+ // Gets the bridge parameters for a given node ID. If the node
+ // is not currently used as a bridge, returns null.
+ let getBridge = async function(controller, id) {
+ let bridges = await controller.getConf("bridge");
+ if (bridges) {
+ for (let bridge of bridges) {
+ if (bridge.ID && bridge.ID.toUpperCase() === id.toUpperCase()) {
+ return bridge;
+ }
}
}
- }
- return null;
-};
-
-// nodeDataForID(controller, id)__.
-// Returns the type, IP addresses and country code of a node with given ID.
-// Example: `nodeDataForID(controller, "20BC91DC525C3DC9974B29FBEAB51230DE024C44")`
-// => `{ type: "default", ipAddrs: ["12.23.34.45", "2001:db8::"], countryCode: "fr" }`
-let nodeDataForID = async function (controller, id) {
- let result = {ipAddrs: []};
- const bridge = await getBridge(controller, id); // type, ip, countryCode;
- const addrRe = /^\[?([^\]]+)\]?:\d+$/
- if (bridge) {
- result.type = "bridge";
- result.bridgeType = bridge.type;
- // Attempt to get an IP address from bridge address string.
- try {
- const ip = bridge.address.match(addrRe)[1];
- if (!ip.startsWith("0.")) {
- result.ipAddrs = [ip];
- }
- } catch (e) {
- }
- } else {
- // either dealing with a relay, or a bridge whose fingerprint is not saved in torrc
- try {
- const statusMap = await controller.getInfo("ns/id/" + id);
- result.type = "default";
- if (!statusMap.IP.startsWith("0.")) {
- result.ipAddrs.push(statusMap.IP);
- }
+ return null;
+ };
+
+ // nodeDataForID(controller, id)__.
+ // Returns the type, IP addresses and country code of a node with given ID.
+ // Example: `nodeDataForID(controller, "20BC91DC525C3DC9974B29FBEAB51230DE024C44")`
+ // => `{ type: "default", ipAddrs: ["12.23.34.45", "2001:db8::"], countryCode: "fr" }`
+ let nodeDataForID = async function(controller, id) {
+ let result = { ipAddrs: [] };
+ const bridge = await getBridge(controller, id); // type, ip, countryCode;
+ const addrRe = /^\[?([^\]]+)\]?:\d+$/;
+ if (bridge) {
+ result.type = "bridge";
+ result.bridgeType = bridge.type;
+ // Attempt to get an IP address from bridge address string.
+ try {
+ const ip = bridge.address.match(addrRe)[1];
+ if (!ip.startsWith("0.")) {
+ result.ipAddrs = [ip];
+ }
+ } catch (e) {}
+ } else {
+ // either dealing with a relay, or a bridge whose fingerprint is not saved in torrc
try {
- result.ipAddrs.push(statusMap.IPv6.match(addrRe)[1]);
+ const statusMap = await controller.getInfo("ns/id/" + id);
+ result.type = "default";
+ if (!statusMap.IP.startsWith("0.")) {
+ result.ipAddrs.push(statusMap.IP);
+ }
+ try {
+ result.ipAddrs.push(statusMap.IPv6.match(addrRe)[1]);
+ } catch (e) {}
} catch (e) {
+ // getInfo will throw if the given id is not a relay
+ // this probably means we are dealing with a user-provided bridge with no fingerprint
+ result.type = "bridge";
+ // we don't know the ip/ipv6 or type, so leave blank
+ result.ipAddrs = [];
+ result.bridgeType = "";
}
- } catch (e) {
- // getInfo will throw if the given id is not a relay
- // this probably means we are dealing with a user-provided bridge with no fingerprint
- result.type = "bridge";
- // we don't know the ip/ipv6 or type, so leave blank
- result.ipAddrs = [];
- result.bridgeType = "";
}
- }
- if (result.ipAddrs.length > 0) {
- // Get the country code for the node's IP address.
- try {
- const countryCode = await controller.getInfo("ip-to-country/" + result.ipAddrs[0]);
- result.countryCode = countryCode === "??" ? null : countryCode;
- } catch (e) { }
- }
- return result;
-};
-
-// __nodeDataForCircuit(controller, circuitEvent)__.
-// Gets the information for a circuit.
-let nodeDataForCircuit = async function (controller, circuitEvent) {
- let rawIDs = circuitEvent.circuit.map(circ => circ[0]),
+ if (result.ipAddrs.length) {
+ // Get the country code for the node's IP address.
+ try {
+ const countryCode = await controller.getInfo(
+ "ip-to-country/" + result.ipAddrs[0]
+ );
+ result.countryCode = countryCode === "??" ? null : countryCode;
+ } catch (e) {}
+ }
+ return result;
+ };
+
+ // __nodeDataForCircuit(controller, circuitEvent)__.
+ // Gets the information for a circuit.
+ let nodeDataForCircuit = async function(controller, circuitEvent) {
+ let rawIDs = circuitEvent.circuit.map(circ => circ[0]),
// Remove the leading '$' if present.
- ids = rawIDs.map(id => id[0] === "$" ? id.substring(1) : id);
- // Get the node data for all IDs in circuit.
- return Promise.all(ids.map(id => nodeDataForID(controller, id)));
-};
-
-// __getCircuitStatusByID(aController, circuitID)__
-// Returns the circuit status for the circuit with the given ID.
-let getCircuitStatusByID = async function (aController, circuitID) {
- let circuitStatuses = await aController.getInfo("circuit-status");
- if (circuitStatuses) {
- for (let circuitStatus of circuitStatuses) {
- if (circuitStatus.id === circuitID) {
- return circuitStatus;
+ ids = rawIDs.map(id => (id[0] === "$" ? id.substring(1) : id));
+ // Get the node data for all IDs in circuit.
+ return Promise.all(ids.map(id => nodeDataForID(controller, id)));
+ };
+
+ // __getCircuitStatusByID(aController, circuitID)__
+ // Returns the circuit status for the circuit with the given ID.
+ let getCircuitStatusByID = async function(aController, circuitID) {
+ let circuitStatuses = await aController.getInfo("circuit-status");
+ if (circuitStatuses) {
+ for (let circuitStatus of circuitStatuses) {
+ if (circuitStatus.id === circuitID) {
+ return circuitStatus;
+ }
}
}
- }
- return null;
-};
-
-// __collectIsolationData(aController, updateUI)__.
-// Watches for STREAM SENTCONNECT events. When a SENTCONNECT event occurs, then
-// we assume isolation settings (SOCKS username+password) are now fixed for the
-// corresponding circuit. Whenever the first stream on a new circuit is seen,
-// looks up u+p and records the node data in the credentialsToNodeDataMap.
-// We need to update the circuit display immediately after any new node data
-// is received. So the `updateUI` callback will be called at that point.
-// See https://trac.torproject.org/projects/tor/ticket/15493
-let collectIsolationData = function (aController, updateUI) {
- return aController.watchEvent(
- "STREAM",
- streamEvent => streamEvent.StreamStatus === "SENTCONNECT",
- async (streamEvent) => {
- if (!knownCircuitIDs.get(streamEvent.CircuitID)) {
- logger.eclog(3, "streamEvent.CircuitID: " + streamEvent.CircuitID);
- knownCircuitIDs.set(streamEvent.CircuitID, true);
- let circuitStatus = await getCircuitStatusByID(aController, streamEvent.CircuitID),
- credentials = circuitStatus ?
- (trimQuotes(circuitStatus.SOCKS_USERNAME) + "|" +
- trimQuotes(circuitStatus.SOCKS_PASSWORD)) :
- null;
- if (credentials) {
- let nodeData = await nodeDataForCircuit(aController, circuitStatus);
- credentialsToNodeDataMap.set(credentials, nodeData);
- updateUI();
+ return null;
+ };
+
+ // __collectIsolationData(aController, updateUI)__.
+ // Watches for STREAM SENTCONNECT events. When a SENTCONNECT event occurs, then
+ // we assume isolation settings (SOCKS username+password) are now fixed for the
+ // corresponding circuit. Whenever the first stream on a new circuit is seen,
+ // looks up u+p and records the node data in the credentialsToNodeDataMap.
+ // We need to update the circuit display immediately after any new node data
+ // is received. So the `updateUI` callback will be called at that point.
+ // See https://trac.torproject.org/projects/tor/ticket/15493
+ let collectIsolationData = function(aController, updateUI) {
+ return aController.watchEvent(
+ "STREAM",
+ streamEvent => streamEvent.StreamStatus === "SENTCONNECT",
+ async streamEvent => {
+ if (!knownCircuitIDs.get(streamEvent.CircuitID)) {
+ logger.eclog(3, "streamEvent.CircuitID: " + streamEvent.CircuitID);
+ knownCircuitIDs.set(streamEvent.CircuitID, true);
+ let circuitStatus = await getCircuitStatusByID(
+ aController,
+ streamEvent.CircuitID
+ ),
+ credentials = circuitStatus
+ ? trimQuotes(circuitStatus.SOCKS_USERNAME) +
+ "|" +
+ trimQuotes(circuitStatus.SOCKS_PASSWORD)
+ : null;
+ if (credentials) {
+ let nodeData = await nodeDataForCircuit(aController, circuitStatus);
+ credentialsToNodeDataMap.set(credentials, nodeData);
+ updateUI();
+ }
}
}
- });
-};
-
-// __browserForChannel(channel)__.
-// Returns the browser that loaded a given channel.
-let browserForChannel = function (channel) {
- if (!channel) return null;
- let chan = channel.QueryInterface(Ci.nsIChannel);
- let callbacks = chan.notificationCallbacks;
- if (!callbacks) return null;
- let loadContext;
- try {
- loadContext = callbacks.getInterface(Ci.nsILoadContext);
- } catch (e) {
- // Ignore
- return null;
- }
- if (!loadContext) return null;
- return loadContext.topFrameElement;
-};
-
-// __collectBrowserCredentials()__.
-// Starts observing http channels. Each channel's proxyInfo
-// username and password is recorded for the channel's browser.
-let collectBrowserCredentials = function () {
- return observe("http-on-modify-request", chan => {
+ );
+ };
+
+ // __browserForChannel(channel)__.
+ // Returns the browser that loaded a given channel.
+ let browserForChannel = function(channel) {
+ if (!channel) {
+ return null;
+ }
+ let chan = channel.QueryInterface(Ci.nsIChannel);
+ let callbacks = chan.notificationCallbacks;
+ if (!callbacks) {
+ return null;
+ }
+ let loadContext;
try {
- let proxyInfo = chan.QueryInterface(Ci.nsIProxiedChannel).proxyInfo;
- let browser = browserForChannel(chan);
- if (browser && proxyInfo) {
- if (!browserToCredentialsMap.has(browser)) {
- browserToCredentialsMap.set(browser, new Map());
+ loadContext = callbacks.getInterface(Ci.nsILoadContext);
+ } catch (e) {
+ // Ignore
+ return null;
+ }
+ if (!loadContext) {
+ return null;
+ }
+ return loadContext.topFrameElement;
+ };
+
+ // __collectBrowserCredentials()__.
+ // Starts observing http channels. Each channel's proxyInfo
+ // username and password is recorded for the channel's browser.
+ let collectBrowserCredentials = function() {
+ return observe("http-on-modify-request", chan => {
+ try {
+ let proxyInfo = chan.QueryInterface(Ci.nsIProxiedChannel).proxyInfo;
+ let browser = browserForChannel(chan);
+ if (browser && proxyInfo) {
+ if (!browserToCredentialsMap.has(browser)) {
+ browserToCredentialsMap.set(browser, new Map());
+ }
+ let domainMap = browserToCredentialsMap.get(browser);
+ domainMap.set(proxyInfo.username, [
+ proxyInfo.username,
+ proxyInfo.password,
+ ]);
}
- let domainMap = browserToCredentialsMap.get(browser);
- domainMap.set(proxyInfo.username, [proxyInfo.username,
- proxyInfo.password]);
+ } catch (e) {
+ logger.eclog(
+ 3,
+ `Error collecting browser credentials: ${e.message}, ${chan.URI.spec}`
+ );
}
+ });
+ };
+
+ // ## User interface
+
+ // __uiString__.
+ // Read the localized strings for this UI.
+ let uiString = function(shortName) {
+ return torbutton_get_property_string(
+ "torbutton.circuit_display." + shortName
+ );
+ };
+
+ // __localizedCountryNameFromCode(countryCode)__.
+ // Convert a country code to a localized country name.
+ // Example: `'de'` -> `'Deutschland'` in German locale.
+ let localizedCountryNameFromCode = function(countryCode) {
+ if (!countryCode) {
+ return uiString("unknown_country");
+ }
+ try {
+ return Services.intl.getRegionDisplayNames(undefined, [countryCode])[0];
} catch (e) {
- logger.eclog(3, `Error collecting browser credentials: ${e.message}, ${chan.URI.spec}`);
+ return countryCode.toUpperCase();
}
- });
-};
-
-// ## User interface
-
-// __uiString__.
-// Read the localized strings for this UI.
-let uiString = function (shortName) {
- return torbutton_get_property_string("torbutton.circuit_display." + shortName);
-};
-
-// __localizedCountryNameFromCode(countryCode)__.
-// Convert a country code to a localized country name.
-// Example: `'de'` -> `'Deutschland'` in German locale.
-let localizedCountryNameFromCode = function (countryCode) {
- if (!countryCode) return uiString("unknown_country");
- try {
- return Services.intl.getRegionDisplayNames(undefined, [countryCode])[0];
- } catch (e) {
- return countryCode.toUpperCase();
- }
-};
-
-// __showCircuitDisplay(show)__.
-// If show === true, makes the circuit display visible.
-let showCircuitDisplay = function (show) {
- document.getElementById("circuit-display-container").style.display = show ?
- 'block' : 'none';
-};
-
-// __xmlTree(ns, data)__.
-// Takes an xml namespace, ns, and a
-// data structure representing xml elements like
-// [tag, { attr-key: attr-value }, ...xml-children]
-// and returns nested xml element objects.
-let xmlTree = function xmlTree (ns, data) {
- let [type, attrs, ...children] = data;
- let element = type.startsWith("html:")
- ? document.createXULElement(type)
- : document.createElementNS(ns, type);
- for (let [key, val] of Object.entries(attrs)) {
- element.setAttribute(key, val);
- }
- for (let child of children) {
- if (child !== null && child !== undefined) {
- element.append(typeof child === "string" ? child : xmlTree(ns, child));
+ };
+
+ // __showCircuitDisplay(show)__.
+ // If show === true, makes the circuit display visible.
+ let showCircuitDisplay = function(show) {
+ document.getElementById("circuit-display-container").style.display = show
+ ? "block"
+ : "none";
+ };
+
+ // __xmlTree(ns, data)__.
+ // Takes an xml namespace, ns, and a
+ // data structure representing xml elements like
+ // [tag, { attr-key: attr-value }, ...xml-children]
+ // and returns nested xml element objects.
+ let xmlTree = function xmlTree(ns, data) {
+ let [type, attrs, ...children] = data;
+ let element = type.startsWith("html:")
+ ? document.createXULElement(type)
+ : document.createElementNS(ns, type);
+ for (let [key, val] of Object.entries(attrs)) {
+ element.setAttribute(key, val);
}
- }
- return element;
-};
-
-// __htmlTree(data)__.
-// Takes a data structure representing html elements like
-// [tag, { attr-key: attr-value }, ...html-children]
-// and returns nested html element objects.
-let htmlTree = data => xmlTree("http://www.w3.org/1999/xhtml", data);
-
-// __appendHtml(parent, data)__.
-// Takes a data structure representing html elements like
-// [tag, { attr-key: attr-value }, ...html-children]
-// and appends nested html element objects to the parent element.
-let appendHtml = (parent, data) => parent.appendChild(htmlTree(data));
-
-// __circuitCircuitData()__.
-// Obtains the circuit used by the given browser.
-let currentCircuitData = function (browser) {
- if (browser) {
- let firstPartyDomain = getDomainForBrowser(browser);
- let domain = firstPartyDomain || "--unknown--";
- let domainMap = browserToCredentialsMap.get(browser);
- let credentials = domainMap && domainMap.get(domain);
- if (credentials) {
- let [SOCKS_username, SOCKS_password] = credentials;
- let nodeData = credentialsToNodeDataMap.get(`${SOCKS_username}|${SOCKS_password}`);
- let domain = SOCKS_username;
- if (browser.documentURI.host.endsWith(".tor.onion")) {
- const service = Cc["@torproject.org/onion-alias-service;1"].getService(
- Ci.IOnionAliasService
- );
- domain = service.getOnionAlias(browser.documentURI.host);
+ for (let child of children) {
+ if (child !== null && child !== undefined) {
+ element.append(typeof child === "string" ? child : xmlTree(ns, child));
}
- return { domain, nodeData };
}
- }
- return { domain: null, nodeData: null };
-};
-
-// __updateCircuitDisplay()__.
-// Updates the Tor circuit display, showing the current domain
-// and the relay nodes for that domain.
-let updateCircuitDisplay = function () {
- let { domain, nodeData } = currentCircuitData(gBrowser.selectedBrowser);
- if (domain && nodeData) {
- // Update the displayed information for the relay nodes.
- let nodeHtmlList = document.getElementById("circuit-display-nodes");
- let li = (...data) => appendHtml(nodeHtmlList, ["li", {}, ...data]);
- nodeHtmlList.innerHTML = "";
- li(uiString("this_browser"));
- for (let i = 0; i < nodeData.length; ++i) {
- let relayText;
- if (nodeData[i].type === "bridge") {
- relayText = uiString("tor_bridge");
- let bridgeType = nodeData[i].bridgeType;
- if (bridgeType === "meek_lite") {
- relayText += ": meek";
- }
- else if (bridgeType !== "vanilla" && bridgeType !== "") {
- relayText += ": " + bridgeType;
+ return element;
+ };
+
+ // __htmlTree(data)__.
+ // Takes a data structure representing html elements like
+ // [tag, { attr-key: attr-value }, ...html-children]
+ // and returns nested html element objects.
+ let htmlTree = data => xmlTree("http://www.w3.org/1999/xhtml", data);
+
+ // __appendHtml(parent, data)__.
+ // Takes a data structure representing html elements like
+ // [tag, { attr-key: attr-value }, ...html-children]
+ // and appends nested html element objects to the parent element.
+ let appendHtml = (parent, data) => parent.appendChild(htmlTree(data));
+
+ // __circuitCircuitData()__.
+ // Obtains the circuit used by the given browser.
+ let currentCircuitData = function(browser) {
+ if (browser) {
+ let firstPartyDomain = getDomainForBrowser(browser);
+ let domain = firstPartyDomain || "--unknown--";
+ let domainMap = browserToCredentialsMap.get(browser);
+ let credentials = domainMap && domainMap.get(domain);
+ if (credentials) {
+ let [SOCKS_username, SOCKS_password] = credentials;
+ let nodeData = credentialsToNodeDataMap.get(
+ `${SOCKS_username}|${SOCKS_password}`
+ );
+ let domain = SOCKS_username;
+ if (browser.documentURI.host.endsWith(".tor.onion")) {
+ const service = Cc[
+ "@torproject.org/onion-alias-service;1"
+ ].getService(Ci.IOnionAliasService);
+ domain = service.getOnionAlias(browser.documentURI.host);
}
- } else if (nodeData[i].type == "default") {
- relayText = localizedCountryNameFromCode(nodeData[i].countryCode);
+ return { domain, nodeData };
}
- const ipAddrs = nodeData[i].ipAddrs.join(", ");
- li(relayText, " ", ["span", { class: "circuit-ip-address" }, ipAddrs], " ",
- (i === 0 && nodeData[0].type !== "bridge") ?
- ["span", { class: "circuit-guard-info" }, uiString("guard")] : null);
}
+ return { domain: null, nodeData: null };
+ };
- let domainParts = [];
- if (domain.endsWith(".onion")) {
- for (let i = 0; i < 3; ++i) {
- li(uiString("relay"));
+ // __updateCircuitDisplay()__.
+ // Updates the Tor circuit display, showing the current domain
+ // and the relay nodes for that domain.
+ let updateCircuitDisplay = function() {
+ let { domain, nodeData } = currentCircuitData(gBrowser.selectedBrowser);
+ if (domain && nodeData) {
+ // Update the displayed information for the relay nodes.
+ let nodeHtmlList = document.getElementById("circuit-display-nodes");
+ let li = (...data) => appendHtml(nodeHtmlList, ["li", {}, ...data]);
+ nodeHtmlList.innerHTML = "";
+ li(uiString("this_browser"));
+ for (let i = 0; i < nodeData.length; ++i) {
+ let relayText;
+ if (nodeData[i].type === "bridge") {
+ relayText = uiString("tor_bridge");
+ let bridgeType = nodeData[i].bridgeType;
+ if (bridgeType === "meek_lite") {
+ relayText += ": meek";
+ } else if (bridgeType !== "vanilla" && bridgeType !== "") {
+ relayText += ": " + bridgeType;
+ }
+ } else if (nodeData[i].type == "default") {
+ relayText = localizedCountryNameFromCode(nodeData[i].countryCode);
+ }
+ const ipAddrs = nodeData[i].ipAddrs.join(", ");
+ li(
+ relayText,
+ " ",
+ ["span", { class: "circuit-ip-address" }, ipAddrs],
+ " ",
+ i === 0 && nodeData[0].type !== "bridge"
+ ? ["span", { class: "circuit-guard-info" }, uiString("guard")]
+ : null
+ );
}
- if (domain.length > 22) {
- domainParts.push(domain.slice(0, 7), "…", domain.slice(-12));
+
+ let domainParts = [];
+ if (domain.endsWith(".onion")) {
+ for (let i = 0; i < 3; ++i) {
+ li(uiString("relay"));
+ }
+ if (domain.length > 22) {
+ domainParts.push(domain.slice(0, 7), "…", domain.slice(-12));
+ } else {
+ domainParts.push(domain);
+ }
} else {
domainParts.push(domain);
}
- } else {
- domainParts.push(domain);
- }
- // We use a XUL html:span element so that the tooltiptext is displayed.
- li([
- "html:span",
- {
- class: "circuit-onion",
- onclick: `
+ // We use a XUL html:span element so that the tooltiptext is displayed.
+ li([
+ "html:span",
+ {
+ class: "circuit-onion",
+ onclick: `
this.classList.add("circuit-onion-copied");
Cc[
"@mozilla.org/widget/clipboardhelper;1"
].getService(Ci.nsIClipboardHelper).copyString(this.getAttribute("data-onion"))
`,
- "data-onion": domain,
- "data-text-clicktocopy": torbutton_get_property_string("torbutton.circuit_display.click_to_copy"),
- "data-text-copied": torbutton_get_property_string("torbutton.circuit_display.copied"),
- tooltiptext: domain,
- },
- ...domainParts,
- ]);
-
- // Hide the note about guards if we are using a bridge.
- document.getElementById("circuit-guard-note-container").style.display =
- (nodeData[0].type === "bridge") ? "none" : "block";
- } else {
- // Only show the Tor circuit if we have credentials and node data.
- logger.eclog(4, "no SOCKS credentials found for current document.");
- }
- showCircuitDisplay(domain && nodeData);
-};
-
-// __syncDisplayWithSelectedTab(syncOn)__.
-// Whenever the user starts to open the popup menu, make sure the display
-// is the correct one for this tab. It's also possible that a new site
-// can be loaded while the popup menu is open.
-// Update the display if this happens.
-let syncDisplayWithSelectedTab = (function() {
- let listener = { onLocationChange : function (aBrowser) {
- if (aBrowser === gBrowser.selectedBrowser) {
- updateCircuitDisplay();
- }
- } };
- return function (syncOn) {
- let popupMenu = document.getElementById("identity-popup");
- if (syncOn) {
- // Update the circuit display just before the popup menu is shown.
- popupMenu.addEventListener("popupshowing", updateCircuitDisplay);
- // If the currently selected tab has been sent to a new location,
- // update the circuit to reflect that.
- gBrowser.addTabsProgressListener(listener);
+ "data-onion": domain,
+ "data-text-clicktocopy": torbutton_get_property_string(
+ "torbutton.circuit_display.click_to_copy"
+ ),
+ "data-text-copied": torbutton_get_property_string(
+ "torbutton.circuit_display.copied"
+ ),
+ tooltiptext: domain,
+ },
+ ...domainParts,
+ ]);
+
+ // Hide the note about guards if we are using a bridge.
+ document.getElementById("circuit-guard-note-container").style.display =
+ nodeData[0].type === "bridge" ? "none" : "block";
} else {
- // Stop syncing.
- gBrowser.removeTabsProgressListener(listener);
- popupMenu.removeEventListener("popupshowing", updateCircuitDisplay);
- // Hide the display.
- showCircuitDisplay(false);
+ // Only show the Tor circuit if we have credentials and node data.
+ logger.eclog(4, "no SOCKS credentials found for current document.");
}
+ showCircuitDisplay(domain && nodeData);
};
-})();
-// __setupGuardNote()__.
-// Call once to show the Guard note as intended.
-let setupGuardNote = function () {
- let guardNote = document.getElementById("circuit-guard-note-container");
- let guardNoteString = uiString("guard_note");
- let learnMoreString = uiString("learn_more");
- let [noteBefore, name, noteAfter] = guardNoteString.split(/[\[\]]/);
- let localeCode = getLocale();
- appendHtml(guardNote,
- ["div", {},
- noteBefore, ["span", {class: "circuit-guard-name"}, name],
- noteAfter, " ",
- ["span", {onclick: `gBrowser.selectedTab = gBrowser.addWebTab('https://support.torproject.org/${localeCode}/tbb/tbb-2/');`,
- class: "circuit-link"},
- learnMoreString]]);
-};
-
-// __ensureCorrectPopupDimensions()__.
-// Make sure the identity popup always displays with the correct height.
-let ensureCorrectPopupDimensions = function () {
- let setDimensions = () => {
- setTimeout(() => {
- let view = document.querySelector("#identity-popup-multiView .panel-viewcontainer");
- let stack = document.querySelector("#identity-popup-multiView .panel-viewstack");
+ // __syncDisplayWithSelectedTab(syncOn)__.
+ // Whenever the user starts to open the popup menu, make sure the display
+ // is the correct one for this tab. It's also possible that a new site
+ // can be loaded while the popup menu is open.
+ // Update the display if this happens.
+ let syncDisplayWithSelectedTab = (function() {
+ let listener = {
+ onLocationChange(aBrowser) {
+ if (aBrowser === gBrowser.selectedBrowser) {
+ updateCircuitDisplay();
+ }
+ },
+ };
+ return function(syncOn) {
+ let popupMenu = document.getElementById("identity-popup");
+ if (syncOn) {
+ // Update the circuit display just before the popup menu is shown.
+ popupMenu.addEventListener("popupshowing", updateCircuitDisplay);
+ // If the currently selected tab has been sent to a new location,
+ // update the circuit to reflect that.
+ gBrowser.addTabsProgressListener(listener);
+ } else {
+ // Stop syncing.
+ gBrowser.removeTabsProgressListener(listener);
+ popupMenu.removeEventListener("popupshowing", updateCircuitDisplay);
+ // Hide the display.
+ showCircuitDisplay(false);
+ }
+ };
+ })();
+
+ // __setupGuardNote()__.
+ // Call once to show the Guard note as intended.
+ let setupGuardNote = function() {
+ let guardNote = document.getElementById("circuit-guard-note-container");
+ let guardNoteString = uiString("guard_note");
+ let learnMoreString = uiString("learn_more");
+ let [noteBefore, name, noteAfter] = guardNoteString.split(/[\[\]]/);
+ let localeCode = getLocale();
+ appendHtml(guardNote, [
+ "div",
+ {},
+ noteBefore,
+ ["span", { class: "circuit-guard-name" }, name],
+ noteAfter,
+ " ",
+ [
+ "span",
+ {
+ onclick: `gBrowser.selectedTab = gBrowser.addWebTab('https://support.torproject.org/${localeCode}/tbb/tbb-2/');`,
+ class: "circuit-link",
+ },
+ learnMoreString,
+ ],
+ ]);
+ };
+
+ // __ensureCorrectPopupDimensions()__.
+ // Make sure the identity popup always displays with the correct height.
+ let ensureCorrectPopupDimensions = function() {
+ let setDimensions = () => {
+ setTimeout(() => {
+ let view = document.querySelector(
+ "#identity-popup-multiView .panel-viewcontainer"
+ );
+ let stack = document.querySelector(
+ "#identity-popup-multiView .panel-viewstack"
+ );
+ let view2 = document.getElementById("identity-popup-mainView");
+ if (view && stack && view2) {
+ let newWidth = Math.max(
+ ...[...view2.children].map(el => el.clientWidth)
+ );
+ let newHeight = stack.clientHeight;
+ stack.setAttribute("width", newWidth);
+ view2.style.minWidth = view2.style.maxWidth = newWidth + "px";
+ view.setAttribute("width", newWidth);
+ view.setAttribute("height", newHeight);
+ }
+ }, 0);
+ };
+ let removeDimensions = () => {
+ let view = document.querySelector(
+ "#identity-popup-multiView .panel-viewcontainer"
+ );
+ let stack = document.querySelector(
+ "#identity-popup-multiView .panel-viewstack"
+ );
let view2 = document.getElementById("identity-popup-mainView");
if (view && stack && view2) {
- let newWidth = Math.max(...[...view2.children].map(el => el.clientWidth));
- let newHeight = stack.clientHeight;
- stack.setAttribute("width", newWidth);
- view2.style.minWidth = view2.style.maxWidth = newWidth + "px";
- view.setAttribute("width", newWidth);
- view.setAttribute("height", newHeight);
+ view.removeAttribute("width");
+ view.removeAttribute("height");
+ stack.removeAttribute("width");
+ view2.style.minWidth = view2.style.maxWidth = "";
}
- }, 0);
+ };
+ let popupMenu = document.getElementById("identity-popup");
+ popupMenu.addEventListener("popupshowing", setDimensions);
+ popupMenu.addEventListener("popuphiding", removeDimensions);
+ return () => {
+ popupMenu.removeEventListener("popupshowing", setDimensions);
+ popupMenu.removeEventListener("popuphiding", removeDimensions);
+ };
};
- let removeDimensions = () => {
- let view = document.querySelector("#identity-popup-multiView .panel-viewcontainer");
- let stack = document.querySelector("#identity-popup-multiView .panel-viewstack");
- let view2 = document.getElementById("identity-popup-mainView");
- if (view && stack && view2) {
- view.removeAttribute("width");
- view.removeAttribute("height");
- stack.removeAttribute("width");
- view2.style.minWidth = view2.style.maxWidth = "";
+
+ // ## Main function
+
+ // __setupDisplay(enablePrefName)__.
+ // Once called, the Tor circuit display will be started whenever
+ // the "enablePref" is set to true, and stopped when it is set to false.
+ // A reference to this function (called createTorCircuitDisplay) is exported as a global.
+ let setupDisplay = function(enablePrefName) {
+ // From 79 on the identity popup is initialized lazily
+ if (gIdentityHandler._initializePopup) {
+ gIdentityHandler._initializePopup();
}
- };
- let popupMenu = document.getElementById("identity-popup");
- popupMenu.addEventListener("popupshowing", setDimensions);
- popupMenu.addEventListener("popuphiding", removeDimensions);
- return () => {
- popupMenu.removeEventListener("popupshowing", setDimensions);
- popupMenu.removeEventListener("popuphiding", removeDimensions);
- };
-};
-
-// ## Main function
-
-// __setupDisplay(enablePrefName)__.
-// Once called, the Tor circuit display will be started whenever
-// the "enablePref" is set to true, and stopped when it is set to false.
-// A reference to this function (called createTorCircuitDisplay) is exported as a global.
-let setupDisplay = function (enablePrefName) {
- // From 79 on the identity popup is initialized lazily
- if (gIdentityHandler._initializePopup) {
- gIdentityHandler._initializePopup();
- }
- setupGuardNote();
- let myController = null,
+ setupGuardNote();
+ let myController = null,
stopCollectingIsolationData = null,
stopCollectingBrowserCredentials = null,
stopEnsuringCorrectPopupDimensions = null,
@@ -486,35 +549,47 @@ let setupDisplay = function (enablePrefName) {
myController = null;
}
},
- start = async function () {
+ start = async function() {
if (!myController) {
try {
myController = await wait_for_controller();
syncDisplayWithSelectedTab(true);
- stopCollectingIsolationData = collectIsolationData(myController, updateCircuitDisplay);
+ stopCollectingIsolationData = collectIsolationData(
+ myController,
+ updateCircuitDisplay
+ );
stopCollectingBrowserCredentials = collectBrowserCredentials();
stopEnsuringCorrectPopupDimensions = ensureCorrectPopupDimensions();
} catch (err) {
logger.eclog(5, err);
- logger.eclog(5, "Disabling tor display circuit because of an error.");
+ logger.eclog(
+ 5,
+ "Disabling tor display circuit because of an error."
+ );
myController.close();
stop();
}
- }
- };
- try {
- let unbindPref = bindPrefAndInit(enablePrefName, on => { if (on) start(); else stop(); });
- // When this chrome window is unloaded, we need to unbind the pref.
- window.addEventListener("unload", function () {
- unbindPref();
- stop();
- });
- } catch (e) {
- logger.eclog(5, "Error: " + e.message + "\n" + e.stack);
- }
-};
+ }
+ };
+ try {
+ let unbindPref = bindPrefAndInit(enablePrefName, on => {
+ if (on) {
+ start();
+ } else {
+ stop();
+ }
+ });
+ // When this chrome window is unloaded, we need to unbind the pref.
+ window.addEventListener("unload", function() {
+ unbindPref();
+ stop();
+ });
+ } catch (e) {
+ logger.eclog(5, "Error: " + e.message + "\n" + e.stack);
+ }
+ };
-return setupDisplay;
+ return setupDisplay;
-// Finish createTorCircuitDisplay()
+ // Finish createTorCircuitDisplay()
})();
diff --git a/chrome/content/torbutton.js b/chrome/content/torbutton.js
index fde5e1fa..ec2680f2 100644
--- a/chrome/content/torbutton.js
+++ b/chrome/content/torbutton.js
@@ -3,121 +3,105 @@ var torbutton_init;
var torbutton_new_circuit;
(() => {
-// Bug 1506 P1-P5: This is the main Torbutton overlay file. Much needs to be
-// preserved here, but in an ideal world, most of this code should perhaps be
-// moved into an XPCOM service, and much can also be tossed. See also
-// individual 1506 comments for details.
+ // Bug 1506 P1-P5: This is the main Torbutton overlay file. Much needs to be
+ // preserved here, but in an ideal world, most of this code should perhaps be
+ // moved into an XPCOM service, and much can also be tossed. See also
+ // individual 1506 comments for details.
-// TODO: check for leaks: http://www.mozilla.org/scriptable/avoiding-leaks.html
-// TODO: Double-check there are no strange exploits to defeat:
-// http://kb.mozillazine.org/Links_to_local_pages_don%27t_work
+ // TODO: check for leaks: http://www.mozilla.org/scriptable/avoiding-leaks.html
+ // TODO: Double-check there are no strange exploits to defeat:
+ // http://kb.mozillazine.org/Links_to_local_pages_don%27t_work
-/* global gBrowser, CustomizableUI,
+ /* global gBrowser, CustomizableUI,
createTorCircuitDisplay, gFindBarInitialized,
gFindBar, OpenBrowserWindow, PrivateBrowsingUtils,
Services, AppConstants
*/
-let {
- show_torbrowser_manual,
- unescapeTorString,
- bindPrefAndInit,
- getDomainForBrowser,
- torbutton_safelog,
- torbutton_log,
- torbutton_get_property_string,
-} = ChromeUtils.import("resource://torbutton/modules/utils.js", {});
-let { configureControlPortModule, wait_for_controller } = Cu.import("resource://torbutton/modules/tor-control-port.js", {});
-
-const k_tb_tor_check_failed_topic = "Torbutton:TorCheckFailed";
-
-var m_tb_prefs = Services.prefs;
-
-// status
-var m_tb_wasinited = false;
-var m_tb_is_main_window = false;
-
-var m_tb_control_ipc_file = null; // Set if using IPC (UNIX domain socket).
-var m_tb_control_port = null; // Set if using TCP.
-var m_tb_control_host = null; // Set if using TCP.
-var m_tb_control_pass = null;
-var m_tb_control_desc = null; // For logging.
-
-var m_tb_domWindowUtils = window.windowUtils;
-
-async function clearData(flags) {
- return new Promise((resolve, reject) => {
- Services.clearData.deleteData(flags, {
- onDataDeleted(code) {
- if (code === Cr.NS_OK) {
- resolve();
- } else {
- reject(new Error(`Error deleting data with flags ${flags}: ${code}`));
- }
- },
- });
- });
-}
-
-// Bug 1506 P2: This object keeps Firefox prefs in sync with Torbutton prefs.
-// It probably could stand some simplification (See #3100). It also belongs
-// in a component, not the XUL overlay.
-var torbutton_unique_pref_observer =
-{
- register: function()
- {
- this.forced_ua = false;
- m_tb_prefs.addObserver("extensions.torbutton", this, false);
- m_tb_prefs.addObserver("browser.privatebrowsing.autostart", this, false);
- m_tb_prefs.addObserver("javascript", this, false);
- m_tb_prefs.addObserver("privacy.resistFingerprinting", this, false);
- m_tb_prefs.addObserver("privacy.resistFingerprinting.letterboxing", this, false);
+ let {
+ show_torbrowser_manual,
+ unescapeTorString,
+ bindPrefAndInit,
+ getDomainForBrowser,
+ torbutton_log,
+ torbutton_get_property_string,
+ } = ChromeUtils.import("resource://torbutton/modules/utils.js");
+ let { configureControlPortModule, wait_for_controller } = ChromeUtils.import(
+ "resource://torbutton/modules/tor-control-port.js"
+ );
+
+ const k_tb_tor_check_failed_topic = "Torbutton:TorCheckFailed";
+
+ var m_tb_prefs = Services.prefs;
+
+ // status
+ var m_tb_wasinited = false;
+ var m_tb_is_main_window = false;
+
+ var m_tb_control_ipc_file = null; // Set if using IPC (UNIX domain socket).
+ var m_tb_control_port = null; // Set if using TCP.
+ var m_tb_control_host = null; // Set if using TCP.
+ var m_tb_control_pass = null;
+
+ // Bug 1506 P2: This object keeps Firefox prefs in sync with Torbutton prefs.
+ // It probably could stand some simplification (See #3100). It also belongs
+ // in a component, not the XUL overlay.
+ var torbutton_unique_pref_observer = {
+ register() {
+ this.forced_ua = false;
+ m_tb_prefs.addObserver("extensions.torbutton", this);
+ m_tb_prefs.addObserver("browser.privatebrowsing.autostart", this);
+ m_tb_prefs.addObserver("javascript", this);
+ m_tb_prefs.addObserver("privacy.resistFingerprinting", this);
+ m_tb_prefs.addObserver("privacy.resistFingerprinting.letterboxing", this);
},
- unregister: function()
- {
- m_tb_prefs.removeObserver("extensions.torbutton", this);
- m_tb_prefs.removeObserver("browser.privatebrowsing.autostart", this);
- m_tb_prefs.removeObserver("javascript", this);
- m_tb_prefs.removeObserver("privacy.resistFingerprinting", this);
- m_tb_prefs.removeObserver("privacy.resistFingerprinting.letterboxing", this);
+ unregister() {
+ m_tb_prefs.removeObserver("extensions.torbutton", this);
+ m_tb_prefs.removeObserver("browser.privatebrowsing.autostart", this);
+ m_tb_prefs.removeObserver("javascript", this);
+ m_tb_prefs.removeObserver("privacy.resistFingerprinting", this);
+ m_tb_prefs.removeObserver(
+ "privacy.resistFingerprinting.letterboxing",
+ this
+ );
},
// topic: what event occurred
// subject: what nsIPrefBranch we're observing
// data: which pref has been changed (relative to subject)
- observe: function(subject, topic, data)
- {
- if (topic !== "nsPref:changed") return;
- switch (data) {
- case "browser.privatebrowsing.autostart":
- torbutton_update_disk_prefs();
- break;
- case "extensions.torbutton.use_nontor_proxy":
- torbutton_use_nontor_proxy();
- break;
- case "privacy.resistFingerprinting":
- case "privacy.resistFingerprinting.letterboxing":
- torbutton_update_fingerprinting_prefs();
- break;
- }
- }
-}
+ observe(subject, topic, data) {
+ if (topic !== "nsPref:changed") {
+ return;
+ }
+ switch (data) {
+ case "browser.privatebrowsing.autostart":
+ torbutton_update_disk_prefs();
+ break;
+ case "extensions.torbutton.use_nontor_proxy":
+ torbutton_use_nontor_proxy();
+ break;
+ case "privacy.resistFingerprinting":
+ case "privacy.resistFingerprinting.letterboxing":
+ torbutton_update_fingerprinting_prefs();
+ break;
+ }
+ },
+ };
-var torbutton_tor_check_observer = {
+ var torbutton_tor_check_observer = {
register() {
- this._obsSvc = Services.obs;
- this._obsSvc.addObserver(this, k_tb_tor_check_failed_topic);
+ this._obsSvc = Services.obs;
+ this._obsSvc.addObserver(this, k_tb_tor_check_failed_topic);
},
- unregister: function()
- {
- if (this._obsSvc)
- this._obsSvc.removeObserver(this, k_tb_tor_check_failed_topic);
+ unregister() {
+ if (this._obsSvc) {
+ this._obsSvc.removeObserver(this, k_tb_tor_check_failed_topic);
+ }
},
- observe: function(subject, topic, data)
- {
+ observe(subject, topic, data) {
if (topic === k_tb_tor_check_failed_topic) {
// Update all open about:tor pages.
torbutton_abouttor_message_handler.updateAllOpenPages();
@@ -129,9 +113,9 @@ var torbutton_tor_check_observer = {
if (win == window) {
let foundTab = false;
let tabBrowser = top.gBrowser;
- for (let i = 0; !foundTab && (i < tabBrowser.browsers.length); ++i) {
+ for (let i = 0; !foundTab && i < tabBrowser.browsers.length; ++i) {
let b = tabBrowser.getBrowserAtIndex(i);
- foundTab = (b.currentURI.spec.toLowerCase() == "about:tor");
+ foundTab = b.currentURI.spec.toLowerCase() == "about:tor";
}
if (!foundTab) {
@@ -140,82 +124,102 @@ var torbutton_tor_check_observer = {
}
}
},
-};
+ };
-var torbutton_new_identity_observers = {
- register() {
- Services.obs.addObserver(this, "new-identity-requested");
- },
+ var torbutton_new_identity_observers = {
+ register() {
+ Services.obs.addObserver(this, "new-identity-requested");
+ },
- observe(aSubject, aTopic, aData) {
- if (aTopic !== "new-identity-requested") {
- return;
- }
+ observe(aSubject, aTopic, aData) {
+ if (aTopic !== "new-identity-requested") {
+ return;
+ }
- // Clear the domain isolation state.
- torbutton_log(3, "Clearing domain isolator");
- const domainIsolator = Cc["@torproject.org/domain-isolator;1"].getService(
- Ci.nsISupports
- ).wrappedJSObject;
- domainIsolator.clearIsolation();
-
- torbutton_log(3, "New Identity: Sending NEWNYM");
- // We only support TBB for newnym.
- if (!m_tb_control_pass || (!m_tb_control_ipc_file && !m_tb_control_port)) {
- var warning = torbutton_get_property_string("torbutton.popup.no_newnym");
- torbutton_log(5, "Torbutton cannot safely newnym. It does not have access to the Tor Control Port.");
- window.alert(warning);
- } else {
- var warning = torbutton_get_property_string("torbutton.popup.no_newnym");
- torbutton_send_ctrl_cmd("SIGNAL NEWNYM").then(res => {
- if (!res) {
- torbutton_log(5, "Torbutton was unable to request a new circuit from Tor");
- window.alert(warning);
- }
- }).catch(e => {
- torbutton_log(5, "Torbutton was unable to request a new circuit from Tor " + e);
+ // Clear the domain isolation state.
+ torbutton_log(3, "Clearing domain isolator");
+ const domainIsolator = Cc["@torproject.org/domain-isolator;1"].getService(
+ Ci.nsISupports
+ ).wrappedJSObject;
+ domainIsolator.clearIsolation();
+
+ torbutton_log(3, "New Identity: Sending NEWNYM");
+ // We only support TBB for newnym.
+ if (
+ !m_tb_control_pass ||
+ (!m_tb_control_ipc_file && !m_tb_control_port)
+ ) {
+ const warning = torbutton_get_property_string(
+ "torbutton.popup.no_newnym"
+ );
+ torbutton_log(
+ 5,
+ "Torbutton cannot safely newnym. It does not have access to the Tor Control Port."
+ );
window.alert(warning);
- });
- }
- },
-}
+ } else {
+ const warning = torbutton_get_property_string(
+ "torbutton.popup.no_newnym"
+ );
+ torbutton_send_ctrl_cmd("SIGNAL NEWNYM")
+ .then(res => {
+ if (!res) {
+ torbutton_log(
+ 5,
+ "Torbutton was unable to request a new circuit from Tor"
+ );
+ window.alert(warning);
+ }
+ })
+ .catch(e => {
+ torbutton_log(
+ 5,
+ "Torbutton was unable to request a new circuit from Tor " + e
+ );
+ window.alert(warning);
+ });
+ }
+ },
+ };
-function torbutton_is_mobile() {
+ function torbutton_is_mobile() {
return Services.appinfo.OS === "Android";
-}
+ }
-// Bug 1506 P2-P4: This code sets some version variables that are irrelevant.
-// It does read out some important environment variables, though. It is
-// called once per browser window.. This might belong in a component.
-torbutton_init = function() {
- torbutton_log(3, 'called init()');
+ // Bug 1506 P2-P4: This code sets some version variables that are irrelevant.
+ // It does read out some important environment variables, though. It is
+ // called once per browser window.. This might belong in a component.
+ torbutton_init = function() {
+ torbutton_log(3, "called init()");
if (m_tb_wasinited) {
- return;
+ return;
}
m_tb_wasinited = true;
let tlps;
try {
- tlps = Cc["@torproject.org/torlauncher-protocol-service;1"]
- .getService(Ci.nsISupports).wrappedJSObject;
- } catch(e) {}
+ tlps = Cc["@torproject.org/torlauncher-protocol-service;1"].getService(
+ Ci.nsISupports
+ ).wrappedJSObject;
+ } catch (e) {}
// Bug 1506 P4: These vars are very important for New Identity
- var environ = Cc["@mozilla.org/process/environment;1"]
- .getService(Ci.nsIEnvironment);
+ var environ = Cc["@mozilla.org/process/environment;1"].getService(
+ Ci.nsIEnvironment
+ );
if (environ.exists("TOR_CONTROL_PASSWD")) {
- m_tb_control_pass = environ.get("TOR_CONTROL_PASSWD");
+ m_tb_control_pass = environ.get("TOR_CONTROL_PASSWD");
} else if (environ.exists("TOR_CONTROL_COOKIE_AUTH_FILE")) {
- var cookie_path = environ.get("TOR_CONTROL_COOKIE_AUTH_FILE");
- try {
- if ("" != cookie_path) {
- m_tb_control_pass = torbutton_read_authentication_cookie(cookie_path);
- }
- } catch(e) {
- torbutton_log(4, 'unable to read authentication cookie');
+ var cookie_path = environ.get("TOR_CONTROL_COOKIE_AUTH_FILE");
+ try {
+ if ("" != cookie_path) {
+ m_tb_control_pass = torbutton_read_authentication_cookie(cookie_path);
}
+ } catch (e) {
+ torbutton_log(4, "unable to read authentication cookie");
+ }
} else {
try {
// Try to get password from Tor Launcher.
@@ -227,47 +231,47 @@ torbutton_init = function() {
// since Tor Launcher knows how to handle its own preferences and how to
// resolve relative paths.
try {
- m_tb_control_ipc_file = tlps.TorGetControlIPCFile();
- } catch(e) {}
-
- if (m_tb_control_ipc_file) {
- m_tb_control_desc = m_tb_control_ipc_file.path;
- } else {
- if (environ.exists("TOR_CONTROL_PORT")) {
- m_tb_control_port = environ.get("TOR_CONTROL_PORT");
- } else {
- try {
- const kTLControlPortPref = "extensions.torlauncher.control_port";
- m_tb_control_port = m_tb_prefs.getIntPref(kTLControlPortPref);
- } catch(e) {
- // Since we want to disable some features when Tor Launcher is
- // not installed (e.g., New Identity), we do not set a default
- // port value here.
- }
- }
+ m_tb_control_ipc_file = tlps.TorGetControlIPCFile();
+ } catch (e) {}
- if (m_tb_control_port) {
- m_tb_control_desc = "" + m_tb_control_port;
+ if (!m_tb_control_ipc_file) {
+ if (environ.exists("TOR_CONTROL_PORT")) {
+ m_tb_control_port = environ.get("TOR_CONTROL_PORT");
+ } else {
+ try {
+ const kTLControlPortPref = "extensions.torlauncher.control_port";
+ m_tb_control_port = m_tb_prefs.getIntPref(kTLControlPortPref);
+ } catch (e) {
+ // Since we want to disable some features when Tor Launcher is
+ // not installed (e.g., New Identity), we do not set a default
+ // port value here.
}
+ }
- if (environ.exists("TOR_CONTROL_HOST")) {
- m_tb_control_host = environ.get("TOR_CONTROL_HOST");
- } else {
- try {
- const kTLControlHostPref = "extensions.torlauncher.control_host";
- m_tb_control_host = m_tb_prefs.getCharPref(kTLControlHostPref);
- } catch(e) {
- m_tb_control_host = "127.0.0.1";
- }
+ if (environ.exists("TOR_CONTROL_HOST")) {
+ m_tb_control_host = environ.get("TOR_CONTROL_HOST");
+ } else {
+ try {
+ const kTLControlHostPref = "extensions.torlauncher.control_host";
+ m_tb_control_host = m_tb_prefs.getCharPref(kTLControlHostPref);
+ } catch (e) {
+ m_tb_control_host = "127.0.0.1";
}
+ }
}
- configureControlPortModule(m_tb_control_ipc_file, m_tb_control_host,
- m_tb_control_port, m_tb_control_pass);
+ configureControlPortModule(
+ m_tb_control_ipc_file,
+ m_tb_control_host,
+ m_tb_control_port,
+ m_tb_control_pass
+ );
// Add about:tor IPC message listener.
- window.messageManager.addMessageListener("AboutTor:Loaded",
- torbutton_abouttor_message_handler);
+ window.messageManager.addMessageListener(
+ "AboutTor:Loaded",
+ torbutton_abouttor_message_handler
+ );
setupPreferencesForMobile();
@@ -275,361 +279,387 @@ torbutton_init = function() {
torbutton_tor_check_observer.register();
try {
- createTorCircuitDisplay("extensions.torbutton.display_circuit");
- } catch(e) {
- torbutton_log(4, "Error creating the tor circuit display " + e);
+ createTorCircuitDisplay("extensions.torbutton.display_circuit");
+ } catch (e) {
+ torbutton_log(4, "Error creating the tor circuit display " + e);
}
try {
- torbutton_init_user_manual_links();
- } catch(e) {
- torbutton_log(4, "Error loading the user manual " + e);
+ torbutton_init_user_manual_links();
+ } catch (e) {
+ torbutton_log(4, "Error loading the user manual " + e);
}
// Arrange for our about:tor content script to be loaded in each frame.
window.messageManager.loadFrameScript(
- "chrome://torbutton/content/aboutTor/aboutTor-content.js", true);
+ "chrome://torbutton/content/aboutTor/aboutTor-content.js",
+ true
+ );
torbutton_new_identity_observers.register();
- torbutton_log(3, 'init completed');
-}
-
-var torbutton_abouttor_message_handler = {
- // Receive IPC messages from the about:tor content script.
- receiveMessage: async function(aMessage) {
- switch(aMessage.name) {
- case "AboutTor:Loaded":
- aMessage.target.messageManager.sendAsyncMessage("AboutTor:ChromeData",
- await this.getChromeData(true));
- break;
- }
- },
-
- // Send privileged data to all of the about:tor content scripts.
- updateAllOpenPages: async function() {
- window.messageManager.broadcastAsyncMessage("AboutTor:ChromeData",
- await this.getChromeData(false));
- },
-
- // The chrome data contains all of the data needed by the about:tor
- // content process that is only available here (in the chrome process).
- // It is sent to the content process when an about:tor window is opened
- // and in response to events such as the browser noticing that Tor is
- // not working.
- getChromeData: async function(aIsRespondingToPageLoad) {
- let dataObj = {
- mobile: torbutton_is_mobile(),
- updateChannel: AppConstants.MOZ_UPDATE_CHANNEL,
- torOn: await torbutton_tor_check_ok()
- };
-
- if (aIsRespondingToPageLoad) {
- const kShouldNotifyPref = "torbrowser.post_update.shouldNotify";
- if (m_tb_prefs.getBoolPref(kShouldNotifyPref, false)) {
- m_tb_prefs.clearUserPref(kShouldNotifyPref);
- dataObj.hasBeenUpdated = true;
- dataObj.updateMoreInfoURL = this.getUpdateMoreInfoURL();
+ torbutton_log(3, "init completed");
+ };
+
+ var torbutton_abouttor_message_handler = {
+ // Receive IPC messages from the about:tor content script.
+ async receiveMessage(aMessage) {
+ switch (aMessage.name) {
+ case "AboutTor:Loaded":
+ aMessage.target.messageManager.sendAsyncMessage(
+ "AboutTor:ChromeData",
+ await this.getChromeData(true)
+ );
+ break;
}
- }
+ },
- return dataObj;
- },
+ // Send privileged data to all of the about:tor content scripts.
+ async updateAllOpenPages() {
+ window.messageManager.broadcastAsyncMessage(
+ "AboutTor:ChromeData",
+ await this.getChromeData(false)
+ );
+ },
- getUpdateMoreInfoURL: function() {
- try {
- return Services.prefs.getCharPref("torbrowser.post_update.url");
- } catch (e) {}
+ // The chrome data contains all of the data needed by the about:tor
+ // content process that is only available here (in the chrome process).
+ // It is sent to the content process when an about:tor window is opened
+ // and in response to events such as the browser noticing that Tor is
+ // not working.
+ async getChromeData(aIsRespondingToPageLoad) {
+ let dataObj = {
+ mobile: torbutton_is_mobile(),
+ updateChannel: AppConstants.MOZ_UPDATE_CHANNEL,
+ torOn: await torbutton_tor_check_ok(),
+ };
+
+ if (aIsRespondingToPageLoad) {
+ const kShouldNotifyPref = "torbrowser.post_update.shouldNotify";
+ if (m_tb_prefs.getBoolPref(kShouldNotifyPref, false)) {
+ m_tb_prefs.clearUserPref(kShouldNotifyPref);
+ dataObj.hasBeenUpdated = true;
+ dataObj.updateMoreInfoURL = this.getUpdateMoreInfoURL();
+ }
+ }
+
+ return dataObj;
+ },
- // Use the default URL as a fallback.
- return Services.urlFormatter.formatURLPref("startup.homepage_override_url");
+ getUpdateMoreInfoURL() {
+ try {
+ return Services.prefs.getCharPref("torbrowser.post_update.url");
+ } catch (e) {}
+
+ // Use the default URL as a fallback.
+ return Services.urlFormatter.formatURLPref(
+ "startup.homepage_override_url"
+ );
+ },
+ };
+
+ // Bug 1506 P4: Control port interaction. Needed for New Identity.
+ function torbutton_read_authentication_cookie(path) {
+ var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
+ file.initWithPath(path);
+ var fileStream = Cc[
+ "@mozilla.org/network/file-input-stream;1"
+ ].createInstance(Ci.nsIFileInputStream);
+ fileStream.init(file, 1, 0, false);
+ var binaryStream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(
+ Ci.nsIBinaryInputStream
+ );
+ binaryStream.setInputStream(fileStream);
+ var array = binaryStream.readByteArray(fileStream.available());
+ binaryStream.close();
+ fileStream.close();
+ return torbutton_array_to_hexdigits(array);
}
-};
-
-// Bug 1506 P4: Control port interaction. Needed for New Identity.
-function torbutton_socket_readline(input) {
- var str = "";
- var bytes;
- while((bytes = input.readBytes(1)) != "\n") {
- if (bytes != '\r')
- str += bytes;
+
+ // Bug 1506 P4: Control port interaction. Needed for New Identity.
+ function torbutton_array_to_hexdigits(array) {
+ return array
+ .map(function(c) {
+ return String("0" + c.toString(16)).slice(-2);
+ })
+ .join("");
}
- return str;
-}
-
-// Bug 1506 P4: Control port interaction. Needed for New Identity.
-function torbutton_read_authentication_cookie(path) {
- var file = Cc["@mozilla.org/file/local;1"]
- .createInstance(Ci.nsIFile);
- file.initWithPath(path);
- var fileStream = Cc["@mozilla.org/network/file-input-stream;1"]
- .createInstance(Ci.nsIFileInputStream);
- fileStream.init(file, 1, 0, false);
- var binaryStream = Cc["@mozilla.org/binaryinputstream;1"]
- .createInstance(Ci.nsIBinaryInputStream);
- binaryStream.setInputStream(fileStream);
- var array = binaryStream.readByteArray(fileStream.available());
- binaryStream.close();
- fileStream.close();
- return torbutton_array_to_hexdigits(array);
-}
-
-// Bug 1506 P4: Control port interaction. Needed for New Identity.
-function torbutton_array_to_hexdigits(array) {
- return array.map(function(c) {
- return String("0" + c.toString(16)).slice(-2)
- }).join('');
-};
-
-// Bug 1506 P4: Control port interaction. Needed for New Identity.
-//
-// Asynchronously executes a command on the control port.
-// returns the response as a string, or null on error
-async function torbutton_send_ctrl_cmd(command) {
- const getErrorMessage = e => (e && (e.torMessage || e.message)) || "";
- let response = null;
- try {
- const avoidCache = true;
- let torController = await wait_for_controller(avoidCache);
-
- let bytes = await torController.sendCommand(command);
- if (!bytes.startsWith("250")) {
- throw `Unexpected command response on control port '${bytes}'`;
- }
- response = bytes.slice(4);
- torController.close();
- } catch(err) {
- let msg = getErrorMessage(err);
- torbutton_log(4, `Error: ${msg}`);
+ // Bug 1506 P4: Control port interaction. Needed for New Identity.
+ //
+ // Asynchronously executes a command on the control port.
+ // returns the response as a string, or null on error
+ async function torbutton_send_ctrl_cmd(command) {
+ const getErrorMessage = e => (e && (e.torMessage || e.message)) || "";
+ let response = null;
+ try {
+ const avoidCache = true;
+ let torController = await wait_for_controller(avoidCache);
+
+ let bytes = await torController.sendCommand(command);
+ if (!bytes.startsWith("250")) {
+ throw new Error(
+ `Unexpected command response on control port '${bytes}'`
+ );
+ }
+ response = bytes.slice(4);
+
+ torController.close();
+ } catch (err) {
+ let msg = getErrorMessage(err);
+ torbutton_log(4, `Error: ${msg}`);
+ }
+ return response;
}
- return response;
-}
-// Bug 1506 P4: Needed for New IP Address
-torbutton_new_circuit = function() {
- let firstPartyDomain = getDomainForBrowser(gBrowser.selectedBrowser);
+ // Bug 1506 P4: Needed for New IP Address
+ torbutton_new_circuit = function() {
+ let firstPartyDomain = getDomainForBrowser(gBrowser.selectedBrowser);
- let domainIsolator = Cc["@torproject.org/domain-isolator;1"]
- .getService(Ci.nsISupports).wrappedJSObject;
+ let domainIsolator = Cc["@torproject.org/domain-isolator;1"].getService(
+ Ci.nsISupports
+ ).wrappedJSObject;
- domainIsolator.newCircuitForDomain(firstPartyDomain);
+ domainIsolator.newCircuitForDomain(firstPartyDomain);
- gBrowser.reloadWithFlags(Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE);
-}
+ gBrowser.reloadWithFlags(Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE);
+ };
-/* Called when we switch the use_nontor_proxy pref in either direction.
- *
- * Enables/disables domain isolation and then does new identity
- */
-function torbutton_use_nontor_proxy()
-{
- let domainIsolator = Cc["@torproject.org/domain-isolator;1"]
- .getService(Ci.nsISupports).wrappedJSObject;
-
- if (m_tb_prefs.getBoolPref("extensions.torbutton.use_nontor_proxy")) {
- // Disable domain isolation
- domainIsolator.disableIsolation();
- } else {
- domainIsolator.enableIsolation();
+ /* Called when we switch the use_nontor_proxy pref in either direction.
+ *
+ * Enables/disables domain isolation and then does new identity
+ */
+ function torbutton_use_nontor_proxy() {
+ let domainIsolator = Cc["@torproject.org/domain-isolator;1"].getService(
+ Ci.nsISupports
+ ).wrappedJSObject;
+
+ if (m_tb_prefs.getBoolPref("extensions.torbutton.use_nontor_proxy")) {
+ // Disable domain isolation
+ domainIsolator.disableIsolation();
+ } else {
+ domainIsolator.enableIsolation();
+ }
}
-}
-
-async function torbutton_do_tor_check()
-{
- let checkSvc = Cc["@torproject.org/torbutton-torCheckService;1"]
- .getService(Ci.nsISupports).wrappedJSObject;
- if (m_tb_prefs.getBoolPref("extensions.torbutton.use_nontor_proxy") ||
- !m_tb_prefs.getBoolPref("extensions.torbutton.test_enabled"))
- return; // Only do the check once.
-
- // If we have a tor control port and transparent torification is off,
- // perform a check via the control port.
- const kEnvSkipControlPortTest = "TOR_SKIP_CONTROLPORTTEST";
- const kEnvUseTransparentProxy = "TOR_TRANSPROXY";
- var env = Cc["@mozilla.org/process/environment;1"]
- .getService(Ci.nsIEnvironment);
- if ((m_tb_control_ipc_file || m_tb_control_port) &&
+
+ async function torbutton_do_tor_check() {
+ let checkSvc = Cc["@torproject.org/torbutton-torCheckService;1"].getService(
+ Ci.nsISupports
+ ).wrappedJSObject;
+ if (
+ m_tb_prefs.getBoolPref("extensions.torbutton.use_nontor_proxy") ||
+ !m_tb_prefs.getBoolPref("extensions.torbutton.test_enabled")
+ ) {
+ return;
+ } // Only do the check once.
+
+ // If we have a tor control port and transparent torification is off,
+ // perform a check via the control port.
+ const kEnvSkipControlPortTest = "TOR_SKIP_CONTROLPORTTEST";
+ const kEnvUseTransparentProxy = "TOR_TRANSPROXY";
+ var env = Cc["@mozilla.org/process/environment;1"].getService(
+ Ci.nsIEnvironment
+ );
+ if (
+ (m_tb_control_ipc_file || m_tb_control_port) &&
!env.exists(kEnvUseTransparentProxy) &&
!env.exists(kEnvSkipControlPortTest) &&
- m_tb_prefs.getBoolPref("extensions.torbutton.local_tor_check")) {
- if (await torbutton_local_tor_check())
- checkSvc.statusOfTorCheck = checkSvc.kCheckSuccessful;
- else {
- // The check failed. Update toolbar icon and tooltip.
- checkSvc.statusOfTorCheck = checkSvc.kCheckFailed;
+ m_tb_prefs.getBoolPref("extensions.torbutton.local_tor_check")
+ ) {
+ if (await torbutton_local_tor_check()) {
+ checkSvc.statusOfTorCheck = checkSvc.kCheckSuccessful;
+ } else {
+ // The check failed. Update toolbar icon and tooltip.
+ checkSvc.statusOfTorCheck = checkSvc.kCheckFailed;
+ }
+ } else {
+ // A local check is not possible, so perform a remote check.
+ torbutton_initiate_remote_tor_check();
}
}
- else {
- // A local check is not possible, so perform a remote check.
- torbutton_initiate_remote_tor_check();
- }
-}
-
-async function torbutton_local_tor_check()
-{
- let didLogError = false;
-
- let proxyType = m_tb_prefs.getIntPref("network.proxy.type");
- if (0 == proxyType)
- return false;
-
- // Ask tor for its SOCKS listener address and port and compare to the
- // browser preferences.
- const kCmdArg = "net/listeners/socks";
- let resp = await torbutton_send_ctrl_cmd("GETINFO " + kCmdArg);
- if (!resp)
- return false;
-
- function logUnexpectedResponse()
- {
- if (!didLogError) {
- didLogError = true;
- torbutton_log(5, "Local Tor check: unexpected GETINFO response: " + resp);
+
+ async function torbutton_local_tor_check() {
+ let didLogError = false;
+
+ let proxyType = m_tb_prefs.getIntPref("network.proxy.type");
+ if (0 == proxyType) {
+ return false;
}
- }
- function removeBrackets(aStr)
- {
- // Remove enclosing square brackets if present.
- if (aStr.startsWith('[') && aStr.endsWith(']'))
- return aStr.substr(1, aStr.length - 2);
+ // Ask tor for its SOCKS listener address and port and compare to the
+ // browser preferences.
+ const kCmdArg = "net/listeners/socks";
+ let resp = await torbutton_send_ctrl_cmd("GETINFO " + kCmdArg);
+ if (!resp) {
+ return false;
+ }
- return aStr;
- }
+ function logUnexpectedResponse() {
+ if (!didLogError) {
+ didLogError = true;
+ torbutton_log(
+ 5,
+ "Local Tor check: unexpected GETINFO response: " + resp
+ );
+ }
+ }
- // Sample response: net/listeners/socks="127.0.0.1:9149" "127.0.0.1:9150"
- // First, check for and remove the command argument prefix.
- if (0 != resp.indexOf(kCmdArg + '=')) {
- logUnexpectedResponse();
- return false;
- }
- resp = resp.substr(kCmdArg.length + 1);
-
- // Retrieve configured proxy settings and check each listener against them.
- // When the SOCKS prefs are set to use IPC (e.g., a Unix domain socket), a
- // file URL should be present in network.proxy.socks.
- // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1211567
- let socksAddr = m_tb_prefs.getCharPref("network.proxy.socks");
- let socksPort = m_tb_prefs.getIntPref("network.proxy.socks_port");
- let socksIPCPath;
- if (socksAddr && socksAddr.startsWith("file:")) {
- // Convert the file URL to a file path.
- try {
- let ioService = Services.io;
- let fph = ioService.getProtocolHandler("file")
- .QueryInterface(Ci.nsIFileProtocolHandler);
- socksIPCPath = fph.getFileFromURLSpec(socksAddr).path;
- } catch (e) {
- torbutton_log(5, "Local Tor check: IPC file error: " + e);
+ function removeBrackets(aStr) {
+ // Remove enclosing square brackets if present.
+ if (aStr.startsWith("[") && aStr.endsWith("]")) {
+ return aStr.substr(1, aStr.length - 2);
+ }
+
+ return aStr;
+ }
+
+ // Sample response: net/listeners/socks="127.0.0.1:9149" "127.0.0.1:9150"
+ // First, check for and remove the command argument prefix.
+ if (0 != resp.indexOf(kCmdArg + "=")) {
+ logUnexpectedResponse();
return false;
}
- } else {
- socksAddr = removeBrackets(socksAddr);
- }
+ resp = resp.substr(kCmdArg.length + 1);
+
+ // Retrieve configured proxy settings and check each listener against them.
+ // When the SOCKS prefs are set to use IPC (e.g., a Unix domain socket), a
+ // file URL should be present in network.proxy.socks.
+ // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1211567
+ let socksAddr = m_tb_prefs.getCharPref("network.proxy.socks");
+ let socksPort = m_tb_prefs.getIntPref("network.proxy.socks_port");
+ let socksIPCPath;
+ if (socksAddr && socksAddr.startsWith("file:")) {
+ // Convert the file URL to a file path.
+ try {
+ let ioService = Services.io;
+ let fph = ioService
+ .getProtocolHandler("file")
+ .QueryInterface(Ci.nsIFileProtocolHandler);
+ socksIPCPath = fph.getFileFromURLSpec(socksAddr).path;
+ } catch (e) {
+ torbutton_log(5, "Local Tor check: IPC file error: " + e);
+ return false;
+ }
+ } else {
+ socksAddr = removeBrackets(socksAddr);
+ }
+
+ // Split into quoted strings. This code is adapted from utils.splitAtSpaces()
+ // within tor-control-port.js; someday this code should use the entire
+ // tor-control-port.js framework.
+ let addrArray = [];
+ resp.replace(/((\S*?"(.*?)")+\S*|\S+)/g, function(a, captured) {
+ addrArray.push(captured);
+ });
- // Split into quoted strings. This code is adapted from utils.splitAtSpaces()
- // within tor-control-port.js; someday this code should use the entire
- // tor-control-port.js framework.
- let addrArray = [];
- resp.replace(/((\S*?"(.*?)")+\S*|\S+)/g, function (a, captured) {
- addrArray.push(captured);
- });
-
- let foundSocksListener = false;
- for (let i = 0; !foundSocksListener && (i < addrArray.length); ++i) {
- let addr;
- try { addr = unescapeTorString(addrArray[i]); } catch (e) {}
- if (!addr)
- continue;
-
- // Remove double quotes if present.
- let len = addr.length;
- if ((len > 2) && ('"' == addr.charAt(0)) && ('"' == addr.charAt(len - 1)))
- addr = addr.substring(1, len - 1);
-
- if (addr.startsWith("unix:")) {
- if (!socksIPCPath)
+ let foundSocksListener = false;
+ for (let i = 0; !foundSocksListener && i < addrArray.length; ++i) {
+ let addr;
+ try {
+ addr = unescapeTorString(addrArray[i]);
+ } catch (e) {}
+ if (!addr) {
continue;
+ }
- // Check against the configured UNIX domain socket proxy.
- let path = addr.substring(5);
- torbutton_log(2, "Tor socks listener (Unix domain socket): " + path);
- foundSocksListener = (socksIPCPath === path);
- } else if (!socksIPCPath) {
- // Check against the configured TCP proxy. We expect addr:port where addr
- // may be an IPv6 address; that is, it may contain colon characters.
- // Also, we remove enclosing square brackets before comparing addresses
- // because tor requires them but Firefox does not.
- let idx = addr.lastIndexOf(':');
- if (idx < 0) {
- logUnexpectedResponse();
- } else {
- let torSocksAddr = removeBrackets(addr.substring(0, idx));
- let torSocksPort = parseInt(addr.substring(idx + 1), 10);
- if ((torSocksAddr.length < 1) || isNaN(torSocksPort)) {
+ // Remove double quotes if present.
+ let len = addr.length;
+ if (len > 2 && '"' == addr.charAt(0) && '"' == addr.charAt(len - 1)) {
+ addr = addr.substring(1, len - 1);
+ }
+
+ if (addr.startsWith("unix:")) {
+ if (!socksIPCPath) {
+ continue;
+ }
+
+ // Check against the configured UNIX domain socket proxy.
+ let path = addr.substring(5);
+ torbutton_log(2, "Tor socks listener (Unix domain socket): " + path);
+ foundSocksListener = socksIPCPath === path;
+ } else if (!socksIPCPath) {
+ // Check against the configured TCP proxy. We expect addr:port where addr
+ // may be an IPv6 address; that is, it may contain colon characters.
+ // Also, we remove enclosing square brackets before comparing addresses
+ // because tor requires them but Firefox does not.
+ let idx = addr.lastIndexOf(":");
+ if (idx < 0) {
logUnexpectedResponse();
} else {
- torbutton_log(2, "Tor socks listener: " + torSocksAddr + ':'
- + torSocksPort);
- foundSocksListener = ((socksAddr === torSocksAddr) &&
- (socksPort === torSocksPort));
+ let torSocksAddr = removeBrackets(addr.substring(0, idx));
+ let torSocksPort = parseInt(addr.substring(idx + 1), 10);
+ if (torSocksAddr.length < 1 || isNaN(torSocksPort)) {
+ logUnexpectedResponse();
+ } else {
+ torbutton_log(
+ 2,
+ "Tor socks listener: " + torSocksAddr + ":" + torSocksPort
+ );
+ foundSocksListener =
+ socksAddr === torSocksAddr && socksPort === torSocksPort;
+ }
}
}
}
- }
-
- return foundSocksListener;
-} // torbutton_local_tor_check
+ return foundSocksListener;
+ } // torbutton_local_tor_check
-function torbutton_initiate_remote_tor_check() {
- let obsSvc = Services.obs;
- try {
- let checkSvc = Cc["@torproject.org/torbutton-torCheckService;1"]
- .getService(Ci.nsISupports).wrappedJSObject;
+ function torbutton_initiate_remote_tor_check() {
+ let obsSvc = Services.obs;
+ try {
+ let checkSvc = Cc[
+ "@torproject.org/torbutton-torCheckService;1"
+ ].getService(Ci.nsISupports).wrappedJSObject;
let req = checkSvc.createCheckRequest(true); // async
- req.onreadystatechange = function (aEvent) {
- if (req.readyState === 4) {
- let ret = checkSvc.parseCheckResponse(req);
-
- // If we received an error response from check.torproject.org,
- // set the status of the tor check to failure (we don't want
- // to indicate failure if we didn't receive a response).
- if (ret == 2 || ret == 3 || ret == 5 || ret == 6
- || ret == 7 || ret == 8) {
- checkSvc.statusOfTorCheck = checkSvc.kCheckFailed;
- obsSvc.notifyObservers(null, k_tb_tor_check_failed_topic, null);
- } else if (ret == 4) {
- checkSvc.statusOfTorCheck = checkSvc.kCheckSuccessful;
- } // Otherwise, redo the check later
-
- torbutton_log(3, "Tor remote check done. Result: " + ret);
- }
+ req.onreadystatechange = function(aEvent) {
+ if (req.readyState === 4) {
+ let ret = checkSvc.parseCheckResponse(req);
+
+ // If we received an error response from check.torproject.org,
+ // set the status of the tor check to failure (we don't want
+ // to indicate failure if we didn't receive a response).
+ if (
+ ret == 2 ||
+ ret == 3 ||
+ ret == 5 ||
+ ret == 6 ||
+ ret == 7 ||
+ ret == 8
+ ) {
+ checkSvc.statusOfTorCheck = checkSvc.kCheckFailed;
+ obsSvc.notifyObservers(null, k_tb_tor_check_failed_topic);
+ } else if (ret == 4) {
+ checkSvc.statusOfTorCheck = checkSvc.kCheckSuccessful;
+ } // Otherwise, redo the check later
+
+ torbutton_log(3, "Tor remote check done. Result: " + ret);
+ }
};
torbutton_log(3, "Sending async Tor remote check");
req.send(null);
- } catch(e) {
- if (e.result == 0x80004005) // NS_ERROR_FAILURE
- torbutton_log(5, "Tor check failed! Is tor running?");
- else
- torbutton_log(5, "Tor check failed! Tor internal error: "+e);
-
- checkSvc.statusOfTorCheck = checkSvc.kCheckFailed;
- obsSvc.notifyObservers(null, k_tb_tor_check_failed_topic, null);
- }
-} // torbutton_initiate_remote_tor_check()
+ } catch (e) {
+ if (e.result == 0x80004005) {
+ // NS_ERROR_FAILURE
+ torbutton_log(5, "Tor check failed! Is tor running?");
+ } else {
+ torbutton_log(5, "Tor check failed! Tor internal error: " + e);
+ }
-async function torbutton_tor_check_ok()
-{
- await torbutton_do_tor_check();
- let checkSvc = Cc["@torproject.org/torbutton-torCheckService;1"]
- .getService(Ci.nsISupports).wrappedJSObject;
- return (checkSvc.kCheckFailed != checkSvc.statusOfTorCheck);
-}
+ obsSvc.notifyObservers(null, k_tb_tor_check_failed_topic);
+ }
+ } // torbutton_initiate_remote_tor_check()
-function torbutton_update_disk_prefs() {
+ async function torbutton_tor_check_ok() {
+ await torbutton_do_tor_check();
+ let checkSvc = Cc["@torproject.org/torbutton-torCheckService;1"].getService(
+ Ci.nsISupports
+ ).wrappedJSObject;
+ return checkSvc.kCheckFailed != checkSvc.statusOfTorCheck;
+ }
+
+ function torbutton_update_disk_prefs() {
var mode = m_tb_prefs.getBoolPref("browser.privatebrowsing.autostart");
m_tb_prefs.setBoolPref("browser.cache.disk.enable", !mode);
@@ -647,184 +677,205 @@ function torbutton_update_disk_prefs() {
// Force prefs to be synced to disk
Services.prefs.savePrefFile(null);
-}
+ }
-function torbutton_update_fingerprinting_prefs() {
+ function torbutton_update_fingerprinting_prefs() {
var mode = m_tb_prefs.getBoolPref("privacy.resistFingerprinting");
- var letterboxing = m_tb_prefs.getBoolPref("privacy.resistFingerprinting.letterboxing", false);
- m_tb_prefs.setBoolPref("extensions.torbutton.resize_new_windows", mode && !letterboxing);
+ var letterboxing = m_tb_prefs.getBoolPref(
+ "privacy.resistFingerprinting.letterboxing",
+ false
+ );
+ m_tb_prefs.setBoolPref(
+ "extensions.torbutton.resize_new_windows",
+ mode && !letterboxing
+ );
// Force prefs to be synced to disk
Services.prefs.savePrefFile(null);
-}
-
-// Bug 1506 P1: This function just cleans up prefs that got set badly in previous releases
-function torbutton_fixup_old_prefs()
-{
- if(m_tb_prefs.getIntPref('extensions.torbutton.pref_fixup_version') < 1) {
- // TBB 5.0a3 had bad Firefox code that silently flipped this pref on us
- if (m_tb_prefs.prefHasUserValue("browser.newtabpage.enhanced")) {
- m_tb_prefs.clearUserPref("browser.newtabpage.enhanced");
- // TBB 5.0a3 users had all the necessary data cached in
- // directoryLinks.json. This meant that resetting the pref above
- // alone was not sufficient as the tiles features uses the cache
- // even if the pref indicates that feature should be disabled.
- // We flip the preference below as this forces a refetching which
- // effectively results in an empty JSON file due to our spoofed
- // URLs.
- let matchOS = m_tb_prefs.getBoolPref("intl.locale.matchOS");
- m_tb_prefs.setBoolPref("intl.locale.matchOS", !matchOS);
- m_tb_prefs.setBoolPref("intl.locale.matchOS", matchOS);
- }
+ }
- // For some reason, the Share This Page button also survived the
- // TBB 5.0a4 update's attempt to remove it.
- if (m_tb_prefs.prefHasUserValue("browser.uiCustomization.state")) {
- m_tb_prefs.clearUserPref("browser.uiCustomization.state");
- }
+ // Bug 1506 P1: This function just cleans up prefs that got set badly in previous releases
+ function torbutton_fixup_old_prefs() {
+ if (m_tb_prefs.getIntPref("extensions.torbutton.pref_fixup_version") < 1) {
+ // TBB 5.0a3 had bad Firefox code that silently flipped this pref on us
+ if (m_tb_prefs.prefHasUserValue("browser.newtabpage.enhanced")) {
+ m_tb_prefs.clearUserPref("browser.newtabpage.enhanced");
+ // TBB 5.0a3 users had all the necessary data cached in
+ // directoryLinks.json. This meant that resetting the pref above
+ // alone was not sufficient as the tiles features uses the cache
+ // even if the pref indicates that feature should be disabled.
+ // We flip the preference below as this forces a refetching which
+ // effectively results in an empty JSON file due to our spoofed
+ // URLs.
+ let matchOS = m_tb_prefs.getBoolPref("intl.locale.matchOS");
+ m_tb_prefs.setBoolPref("intl.locale.matchOS", !matchOS);
+ m_tb_prefs.setBoolPref("intl.locale.matchOS", matchOS);
+ }
- m_tb_prefs.setIntPref('extensions.torbutton.pref_fixup_version', 1);
+ // For some reason, the Share This Page button also survived the
+ // TBB 5.0a4 update's attempt to remove it.
+ if (m_tb_prefs.prefHasUserValue("browser.uiCustomization.state")) {
+ m_tb_prefs.clearUserPref("browser.uiCustomization.state");
+ }
+
+ m_tb_prefs.setIntPref("extensions.torbutton.pref_fixup_version", 1);
}
-}
+ }
-// ---------------------- Event handlers -----------------
+ // ---------------------- Event handlers -----------------
-// Bug 1506 P1-P3: Most of these observers aren't very important.
-// See their comments for details
-function torbutton_do_main_window_startup()
-{
+ // Bug 1506 P1-P3: Most of these observers aren't very important.
+ // See their comments for details
+ function torbutton_do_main_window_startup() {
torbutton_log(3, "Torbutton main window startup");
m_tb_is_main_window = true;
torbutton_unique_pref_observer.register();
-}
+ }
-// Bug 1506 P4: Most of this function is now useless, save
-// for the very important SOCKS environment vars at the end.
-// Those could probably be rolled into a function with the
-// control port vars, though. See 1506 comments inside.
-function torbutton_do_startup()
-{
- if(m_tb_prefs.getBoolPref("extensions.torbutton.startup")) {
- // Bug 1506: Should probably be moved to an XPCOM component
- torbutton_do_main_window_startup();
+ // Bug 1506 P4: Most of this function is now useless, save
+ // for the very important SOCKS environment vars at the end.
+ // Those could probably be rolled into a function with the
+ // control port vars, though. See 1506 comments inside.
+ function torbutton_do_startup() {
+ if (m_tb_prefs.getBoolPref("extensions.torbutton.startup")) {
+ // Bug 1506: Should probably be moved to an XPCOM component
+ torbutton_do_main_window_startup();
- // For charsets
- torbutton_update_fingerprinting_prefs();
+ // For charsets
+ torbutton_update_fingerprinting_prefs();
- // Bug 30565: sync browser.privatebrowsing.autostart with security.nocertdb
- torbutton_update_disk_prefs();
+ // Bug 30565: sync browser.privatebrowsing.autostart with security.nocertdb
+ torbutton_update_disk_prefs();
- // For general pref fixups to handle pref damage in older versions
- torbutton_fixup_old_prefs();
+ // For general pref fixups to handle pref damage in older versions
+ torbutton_fixup_old_prefs();
- m_tb_prefs.setBoolPref("extensions.torbutton.startup", false);
+ m_tb_prefs.setBoolPref("extensions.torbutton.startup", false);
}
-}
-
-// Bug 1506 P3: Used to decide if we should resize the window.
-//
-// Returns true if the window wind is neither maximized, full screen,
-// ratpoisioned/evilwmed, nor minimized.
-function torbutton_is_windowed(wind) {
- torbutton_log(3, "Window: (" + wind.outerWidth + "," + wind.outerHeight + ") ?= ("
- + wind.screen.availWidth + "," + wind.screen.availHeight + ")");
- if (wind.windowState == Ci.nsIDOMChromeWindow.STATE_MINIMIZED
- || wind.windowState == Ci.nsIDOMChromeWindow.STATE_MAXIMIZED) {
- torbutton_log(2, "Window is minimized/maximized");
- return false;
+ }
+
+ // Bug 1506 P3: Used to decide if we should resize the window.
+ //
+ // Returns true if the window wind is neither maximized, full screen,
+ // ratpoisioned/evilwmed, nor minimized.
+ function torbutton_is_windowed(wind) {
+ torbutton_log(
+ 3,
+ "Window: (" +
+ wind.outerWidth +
+ "," +
+ wind.outerHeight +
+ ") ?= (" +
+ wind.screen.availWidth +
+ "," +
+ wind.screen.availHeight +
+ ")"
+ );
+ if (
+ wind.windowState == Ci.nsIDOMChromeWindow.STATE_MINIMIZED ||
+ wind.windowState == Ci.nsIDOMChromeWindow.STATE_MAXIMIZED
+ ) {
+ torbutton_log(2, "Window is minimized/maximized");
+ return false;
}
if ("fullScreen" in wind && wind.fullScreen) {
- torbutton_log(2, "Window is fullScreen");
- return false;
+ torbutton_log(2, "Window is fullScreen");
+ return false;
}
- if(wind.outerHeight == wind.screen.availHeight
- && wind.outerWidth == wind.screen.availWidth) {
- torbutton_log(3, "Window is ratpoisoned/evilwm'ed");
- return false;
+ if (
+ wind.outerHeight == wind.screen.availHeight &&
+ wind.outerWidth == wind.screen.availWidth
+ ) {
+ torbutton_log(3, "Window is ratpoisoned/evilwm'ed");
+ return false;
}
torbutton_log(2, "Window is normal");
return true;
-}
+ }
-function showSecurityPreferencesPanel(chromeWindow) {
- const tabBrowser = chromeWindow.BrowserApp;
- let settingsTab = null;
+ function showSecurityPreferencesPanel(chromeWindow) {
+ const tabBrowser = chromeWindow.BrowserApp;
+ let settingsTab = null;
- const SECURITY_PREFERENCES_URI = 'chrome://torbutton/content/preferences.xhtml';
+ const SECURITY_PREFERENCES_URI =
+ "chrome://torbutton/content/preferences.xhtml";
- tabBrowser.tabs.some(function (tab) {
+ tabBrowser.tabs.some(function(tab) {
// If the security prefs tab is opened, send the user to it
if (tab.browser.currentURI.spec === SECURITY_PREFERENCES_URI) {
- settingsTab = tab;
- return true;
+ settingsTab = tab;
+ return true;
}
return false;
- });
+ });
- if (settingsTab === null) {
+ if (settingsTab === null) {
// Open up the settings panel in a new tab.
tabBrowser.addTab(SECURITY_PREFERENCES_URI, {
- "selected": true,
- "parentId": tabBrowser.selectedTab.id,
- triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+ selected: true,
+ parentId: tabBrowser.selectedTab.id,
+ triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
});
- } else {
+ } else {
// Activate an existing settings panel tab.
tabBrowser.selectTab(settingsTab);
+ }
}
-}
-function setupPreferencesForMobile() {
- if (!torbutton_is_mobile()) {
- return;
- }
+ function setupPreferencesForMobile() {
+ if (!torbutton_is_mobile()) {
+ return;
+ }
- torbutton_log(4, "Setting up settings preferences for Android.");
+ torbutton_log(4, "Setting up settings preferences for Android.");
- const chromeWindow = Services.wm.getMostRecentWindow('navigator:browser');
+ const chromeWindow = Services.wm.getMostRecentWindow("navigator:browser");
- // Add the extension's chrome menu item to the main browser menu.
- chromeWindow.NativeWindow.menu.add({
- 'name': torbutton_get_property_string("torbutton.security_settings.menu.title"),
- 'callback': showSecurityPreferencesPanel.bind(this, chromeWindow)
- });
-}
+ // Add the extension's chrome menu item to the main browser menu.
+ chromeWindow.NativeWindow.menu.add({
+ name: torbutton_get_property_string(
+ "torbutton.security_settings.menu.title"
+ ),
+ callback: showSecurityPreferencesPanel.bind(this, chromeWindow),
+ });
+ }
-// Bug 1506 P3: This is needed pretty much only for the window resizing.
-// See comments for individual functions for details
-function torbutton_new_window(event)
-{
+ // Bug 1506 P3: This is needed pretty much only for the window resizing.
+ // See comments for individual functions for details
+ function torbutton_new_window(event) {
torbutton_log(3, "New window");
var browser = window.gBrowser;
- if(!browser) {
+ if (!browser) {
torbutton_log(5, "No browser for new window.");
return;
}
if (!m_tb_wasinited) {
- torbutton_init();
+ torbutton_init();
}
torbutton_do_startup();
- let progress = Cc["@mozilla.org/docloaderservice;1"]
- .getService(Ci.nsIWebProgress);
+ let progress = Cc["@mozilla.org/docloaderservice;1"].getService(
+ Ci.nsIWebProgress
+ );
if (torbutton_is_windowed(window)) {
- progress.addProgressListener(torbutton_resizelistener,
- Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
+ progress.addProgressListener(
+ torbutton_resizelistener,
+ Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT
+ );
}
-}
+ }
-// Bug 1506 P2: This is only needed because we have observers
-// in XUL that should be in an XPCOM component
-function torbutton_close_window(event) {
+ // Bug 1506 P2: This is only needed because we have observers
+ // in XUL that should be in an XPCOM component
+ function torbutton_close_window(event) {
torbutton_tor_check_observer.unregister();
- window.removeEventListener("sizemodechange", m_tb_resize_handler,
- false);
+ window.removeEventListener("sizemodechange", m_tb_resize_handler);
// TODO: This is a real ghetto hack.. When the original window
// closes, we need to find another window to handle observing
@@ -832,151 +883,179 @@ function torbutton_close_window(event) {
// majority of torbutton functionality into a XPCOM component..
// But that is a major overhaul..
if (m_tb_is_main_window) {
- torbutton_log(3, "Original window closed. Searching for another");
- var wm = Services.wm;
- var enumerator = wm.getEnumerator("navigator:browser");
- while(enumerator.hasMoreElements()) {
- var win = enumerator.getNext();
- // For some reason, when New Identity is called from a pref
- // observer (ex: torbutton_use_nontor_proxy) on an ASAN build,
- // we sometimes don't have this symbol set in the new window yet.
- // However, the new window will run this init later in that case,
- // as it does in the OSX case.
- if(win != window && "torbutton_do_main_window_startup" in win) {
- torbutton_log(3, "Found another window");
- win.torbutton_do_main_window_startup();
- m_tb_is_main_window = false;
- break;
- }
+ torbutton_log(3, "Original window closed. Searching for another");
+ var wm = Services.wm;
+ var enumerator = wm.getEnumerator("navigator:browser");
+ while (enumerator.hasMoreElements()) {
+ var win = enumerator.getNext();
+ // For some reason, when New Identity is called from a pref
+ // observer (ex: torbutton_use_nontor_proxy) on an ASAN build,
+ // we sometimes don't have this symbol set in the new window yet.
+ // However, the new window will run this init later in that case,
+ // as it does in the OSX case.
+ if (win != window && "torbutton_do_main_window_startup" in win) {
+ torbutton_log(3, "Found another window");
+ win.torbutton_do_main_window_startup();
+ m_tb_is_main_window = false;
+ break;
}
+ }
- torbutton_unique_pref_observer.unregister();
+ torbutton_unique_pref_observer.unregister();
- if(m_tb_is_main_window) { // main window not reset above
- // This happens on Mac OS because they allow firefox
- // to still persist without a navigator window
- torbutton_log(3, "Last window closed. None remain.");
- m_tb_prefs.setBoolPref("extensions.torbutton.startup", true);
- m_tb_is_main_window = false;
- }
+ if (m_tb_is_main_window) {
+ // main window not reset above
+ // This happens on Mac OS because they allow firefox
+ // to still persist without a navigator window
+ torbutton_log(3, "Last window closed. None remain.");
+ m_tb_prefs.setBoolPref("extensions.torbutton.startup", true);
+ m_tb_is_main_window = false;
+ }
}
-}
-
-window.addEventListener('load',torbutton_new_window,false);
-window.addEventListener('unload', torbutton_close_window, false);
-
-var m_tb_resize_handler = null;
-var m_tb_resize_date = null;
-
-// Bug 1506 P1/P3: Setting a fixed window size is important, but
-// probably not for android.
-var torbutton_resizelistener =
-{
- QueryInterface: ChromeUtils.generateQI(["nsIWebProgressListener", "nsISupportsWeakReference"]),
-
- onLocationChange: function(aProgress, aRequest, aURI) {},
- onStateChange: function(aProgress, aRequest, aFlag, aStatus) {
- if (aFlag & Ci.nsIWebProgressListener.STATE_STOP) {
- m_tb_resize_handler = async function() {
- // Wait for end of execution queue to ensure we have correct windowState.
- await new Promise(resolve => setTimeout(resolve, 0));
- if (window.windowState === window.STATE_MAXIMIZED ||
- window.windowState === window.STATE_FULLSCREEN) {
- if (m_tb_prefs.getBoolPref("extensions.torbutton.resize_new_windows") &&
- m_tb_prefs.getIntPref("extensions.torbutton.maximize_warnings_remaining") > 0) {
-
- // Do not add another notification if one is already showing.
- const kNotificationName = "torbutton-maximize-notification";
- let box = gBrowser.getNotificationBox();
- if (box.getNotificationWithValue(kNotificationName))
- return;
-
- // Rate-limit showing our notification if needed.
- if (m_tb_resize_date === null) {
- m_tb_resize_date = Date.now();
- } else {
- // We wait at least another second before we show a new
- // notification. Should be enough to rule out OSes that call our
- // handler rapidly due to internal workings.
- if (Date.now() - m_tb_resize_date < 1000) {
+ }
+
+ window.addEventListener("load", torbutton_new_window);
+ window.addEventListener("unload", torbutton_close_window);
+
+ var m_tb_resize_handler = null;
+ var m_tb_resize_date = null;
+
+ // Bug 1506 P1/P3: Setting a fixed window size is important, but
+ // probably not for android.
+ var torbutton_resizelistener = {
+ QueryInterface: ChromeUtils.generateQI([
+ "nsIWebProgressListener",
+ "nsISupportsWeakReference",
+ ]),
+
+ onLocationChange(aProgress, aRequest, aURI) {},
+ onStateChange(aProgress, aRequest, aFlag, aStatus) {
+ if (aFlag & Ci.nsIWebProgressListener.STATE_STOP) {
+ m_tb_resize_handler = async function() {
+ // Wait for end of execution queue to ensure we have correct windowState.
+ await new Promise(resolve => setTimeout(resolve, 0));
+ if (
+ window.windowState === window.STATE_MAXIMIZED ||
+ window.windowState === window.STATE_FULLSCREEN
+ ) {
+ if (
+ m_tb_prefs.getBoolPref(
+ "extensions.torbutton.resize_new_windows"
+ ) &&
+ m_tb_prefs.getIntPref(
+ "extensions.torbutton.maximize_warnings_remaining"
+ ) > 0
+ ) {
+ // Do not add another notification if one is already showing.
+ const kNotificationName = "torbutton-maximize-notification";
+ let box = gBrowser.getNotificationBox();
+ if (box.getNotificationWithValue(kNotificationName)) {
return;
}
- // Resizing but we need to reset |m_tb_resize_date| now.
- m_tb_resize_date = Date.now();
- }
- // No need to get "OK" translated again.
- let sbSvc = Services.strings;
- let bundle = sbSvc.
- createBundle("chrome://global/locale/commonDialogs.properties");
- let button_label = bundle.GetStringFromName("OK");
-
- let buttons = [{
- label: button_label,
- accessKey: 'O',
- popup: null,
- callback:
- function() {
- m_tb_prefs.setIntPref("extensions.torbutton.maximize_warnings_remaining",
- m_tb_prefs.getIntPref("extensions.torbutton.maximize_warnings_remaining") - 1);
+ // Rate-limit showing our notification if needed.
+ if (m_tb_resize_date === null) {
+ m_tb_resize_date = Date.now();
+ } else {
+ // We wait at least another second before we show a new
+ // notification. Should be enough to rule out OSes that call our
+ // handler rapidly due to internal workings.
+ if (Date.now() - m_tb_resize_date < 1000) {
+ return;
}
- }];
-
- let priority = box.PRIORITY_WARNING_LOW;
- let message =
- torbutton_get_property_string("torbutton.maximize_warning");
+ // Resizing but we need to reset |m_tb_resize_date| now.
+ m_tb_resize_date = Date.now();
+ }
- box.appendNotification(message, kNotificationName, null,
- priority, buttons);
- return;
+ // No need to get "OK" translated again.
+ let sbSvc = Services.strings;
+ let bundle = sbSvc.createBundle(
+ "chrome://global/locale/commonDialogs.properties"
+ );
+ let button_label = bundle.GetStringFromName("OK");
+
+ let buttons = [
+ {
+ label: button_label,
+ accessKey: "O",
+ popup: null,
+ callback() {
+ m_tb_prefs.setIntPref(
+ "extensions.torbutton.maximize_warnings_remaining",
+ m_tb_prefs.getIntPref(
+ "extensions.torbutton.maximize_warnings_remaining"
+ ) - 1
+ );
+ },
+ },
+ ];
+
+ let priority = box.PRIORITY_WARNING_LOW;
+ let message = torbutton_get_property_string(
+ "torbutton.maximize_warning"
+ );
+
+ box.appendNotification(
+ message,
+ kNotificationName,
+ null,
+ priority,
+ buttons
+ );
+ }
}
- }
- }; // m_tb_resize_handler
-
- // We need to handle OSes that auto-maximize windows depending on user
- // settings and/or screen resolution in the start-up phase and users that
- // try to shoot themselves in the foot by maximizing the window manually.
- // We add a listener which is triggerred as soon as the window gets
- // maximized (windowState = 1). We are resizing during start-up but not
- // later as the user should see only a warning there as a stopgap before
- // #14229 lands.
- // Alas, the Firefox window code is handling the event not itself:
- // "// Note the current implementation of SetSizeMode just stores
- // // the new state; it doesn't actually resize. So here we store
- // // the state and pass the event on to the OS."
- // (See: https://mxr.mozilla.org/mozilla-esr31/source/xpfe/appshell/src/
- // nsWebShellWindow.cpp#348)
- // This means we have to cope with race conditions and resizing in the
- // sizemodechange listener is likely to fail. Thus, we add a specific
- // resize listener that is doing the work for us. It seems (at least on
- // Ubuntu) to be the case that maximizing (and then again normalizing) of
- // the window triggers more than one resize event the first being not the
- // one we need. Thus we can't remove the listener after the first resize
- // event got fired. Thus, we have the rather klunky setTimeout() call.
- window.addEventListener("sizemodechange", m_tb_resize_handler, false);
-
- let progress = Cc["@mozilla.org/docloaderservice;1"]
- .getService(Ci.nsIWebProgress);
- progress.removeProgressListener(this);
- }
- }, // onStateChange
-
- onProgressChange: function(aProgress, aRequest, curSelfProgress,
- maxSelfProgress, curTotalProgress,
- maxTotalProgress) {},
- onStatusChange: function(aProgress, aRequest, stat, message) {},
- onSecurityChange: function() {}
-};
-
-// Makes sure the item in the Help Menu and the link in about:tor
-// for the Tor Browser User Manual are only visible when
-// show_torbrowser_manual() returns true.
-function torbutton_init_user_manual_links() {
- let menuitem = document.getElementById("torBrowserUserManual");
- bindPrefAndInit("intl.locale.requested", val => {
- menuitem.hidden = !show_torbrowser_manual();
- torbutton_abouttor_message_handler.updateAllOpenPages();
- });
-}
+ }; // m_tb_resize_handler
+
+ // We need to handle OSes that auto-maximize windows depending on user
+ // settings and/or screen resolution in the start-up phase and users that
+ // try to shoot themselves in the foot by maximizing the window manually.
+ // We add a listener which is triggerred as soon as the window gets
+ // maximized (windowState = 1). We are resizing during start-up but not
+ // later as the user should see only a warning there as a stopgap before
+ // #14229 lands.
+ // Alas, the Firefox window code is handling the event not itself:
+ // "// Note the current implementation of SetSizeMode just stores
+ // // the new state; it doesn't actually resize. So here we store
+ // // the state and pass the event on to the OS."
+ // (See: https://mxr.mozilla.org/mozilla-esr31/source/xpfe/appshell/src/
+ // nsWebShellWindow.cpp#348)
+ // This means we have to cope with race conditions and resizing in the
+ // sizemodechange listener is likely to fail. Thus, we add a specific
+ // resize listener that is doing the work for us. It seems (at least on
+ // Ubuntu) to be the case that maximizing (and then again normalizing) of
+ // the window triggers more than one resize event the first being not the
+ // one we need. Thus we can't remove the listener after the first resize
+ // event got fired. Thus, we have the rather klunky setTimeout() call.
+ window.addEventListener("sizemodechange", m_tb_resize_handler);
+
+ let progress = Cc["@mozilla.org/docloaderservice;1"].getService(
+ Ci.nsIWebProgress
+ );
+ progress.removeProgressListener(this);
+ }
+ }, // onStateChange
+
+ onProgressChange(
+ aProgress,
+ aRequest,
+ curSelfProgress,
+ maxSelfProgress,
+ curTotalProgress,
+ maxTotalProgress
+ ) {},
+ onStatusChange(aProgress, aRequest, stat, message) {},
+ onSecurityChange() {},
+ };
+
+ // Makes sure the item in the Help Menu and the link in about:tor
+ // for the Tor Browser User Manual are only visible when
+ // show_torbrowser_manual() returns true.
+ function torbutton_init_user_manual_links() {
+ let menuitem = document.getElementById("torBrowserUserManual");
+ bindPrefAndInit("intl.locale.requested", val => {
+ menuitem.hidden = !show_torbrowser_manual();
+ torbutton_abouttor_message_handler.updateAllOpenPages();
+ });
+ }
})();
//vim:set ts=4
diff --git a/components/domain-isolator.js b/components/domain-isolator.js
index 06fe1e2e..1c77b577 100644
--- a/components/domain-isolator.js
+++ b/components/domain-isolator.js
@@ -9,15 +9,17 @@
// ### Abbreviations
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+const { XPCOMUtils } = ChromeUtils.import(
+ "resource://gre/modules/XPCOMUtils.jsm"
+);
XPCOMUtils.defineLazyModuleGetters(this, {
ComponentUtils: "resource://gre/modules/ComponentUtils.jsm",
});
// Make the logger available.
-let logger = Cc["@torproject.org/torbutton-logger;1"]
- .getService(Ci.nsISupports).wrappedJSObject;
+let logger = Cc["@torproject.org/torbutton-logger;1"].getService(Ci.nsISupports)
+ .wrappedJSObject;
// Import crypto object (FF 37+).
Cu.importGlobalProperties(["crypto"]);
@@ -29,8 +31,9 @@ let mozilla = {};
// __mozilla.protocolProxyService__.
// Mozilla's protocol proxy service, useful for managing proxy connections made
// by the browser.
-mozilla.protocolProxyService = Cc["@mozilla.org/network/protocol-proxy-service;1"]
- .getService(Ci.nsIProtocolProxyService);
+mozilla.protocolProxyService = Cc[
+ "@mozilla.org/network/protocol-proxy-service;1"
+].getService(Ci.nsIProtocolProxyService);
// __mozilla.registerProxyChannelFilter(filterFunction, positionIndex)__.
// Registers a proxy channel filter with the Mozilla Protocol Proxy Service,
@@ -38,13 +41,16 @@ mozilla.protocolProxyService = Cc["@mozilla.org/network/protocol-proxy-service;1
// The filterFunction should expect two arguments, (aChannel, aProxy),
// where aProxy is the proxy or list of proxies that would be used by default
// for the given channel, and should return a new Proxy or list of Proxies.
-mozilla.registerProxyChannelFilter = function (filterFunction, positionIndex) {
+mozilla.registerProxyChannelFilter = function(filterFunction, positionIndex) {
let proxyFilter = {
- applyFilter : function (aChannel, aProxy, aCallback) {
+ applyFilter(aChannel, aProxy, aCallback) {
aCallback.onProxyFilterResult(filterFunction(aChannel, aProxy));
- }
+ },
};
- mozilla.protocolProxyService.registerChannelFilter(proxyFilter, positionIndex);
+ mozilla.protocolProxyService.registerChannelFilter(
+ proxyFilter,
+ positionIndex
+ );
};
// ## tor functionality.
@@ -66,24 +72,25 @@ tor.unknownDirtySince = Date.now();
// Takes a proxyInfo object (originalProxy) and returns a new proxyInfo
// object with the same properties, except the username is set to the
// the domain, and the password is a nonce.
-tor.socksProxyCredentials = function (originalProxy, domain) {
+tor.socksProxyCredentials = function(originalProxy, domain) {
// Check if we already have a nonce. If not, create
// one for this domain.
if (!tor.noncesForDomains.hasOwnProperty(domain)) {
tor.noncesForDomains[domain] = tor.nonce();
}
let proxy = originalProxy.QueryInterface(Ci.nsIProxyInfo);
- return mozilla.protocolProxyService
- .newProxyInfoWithAuth("socks",
- proxy.host,
- proxy.port,
- domain, // username
- tor.noncesForDomains[domain], // password
- "", // aProxyAuthorizationHeader
- "", // aConnectionIsolationKey
- proxy.flags,
- proxy.failoverTimeout,
- proxy.failoverProxy);
+ return mozilla.protocolProxyService.newProxyInfoWithAuth(
+ "socks",
+ proxy.host,
+ proxy.port,
+ domain, // username
+ tor.noncesForDomains[domain], // password
+ "", // aProxyAuthorizationHeader
+ "", // aConnectionIsolationKey
+ proxy.flags,
+ proxy.failoverTimeout,
+ proxy.failoverProxy
+ );
};
tor.nonce = function() {
@@ -98,7 +105,7 @@ tor.nonce = function() {
let tagStr = "";
for (let i = 0; i < tag.length; i++) {
tagStr += (tag[i] >>> 4).toString(16);
- tagStr += (tag[i] & 0x0F).toString(16);
+ tagStr += (tag[i] & 0x0f).toString(16);
}
return tagStr;
@@ -110,13 +117,16 @@ tor.newCircuitForDomain = function(domain) {
domain = "--unknown--";
}
tor.noncesForDomains[domain] = tor.nonce();
- logger.eclog(3, "New domain isolation for " + domain + ": " + tor.noncesForDomains[domain]);
+ logger.eclog(
+ 3,
+ "New domain isolation for " + domain + ": " + tor.noncesForDomains[domain]
+ );
};
// __tor.clearIsolation()_.
// Clear the isolation state cache, forcing new circuits to be used for all
// subsequent requests.
-tor.clearIsolation = function () {
+tor.clearIsolation = function() {
// Per-domain nonces are stored in a map, so simply re-initialize the map.
tor.noncesForDomains = {};
@@ -130,28 +140,38 @@ tor.clearIsolation = function () {
// to the SOCKS server (the tor client process) with a username (the first party domain)
// and a nonce password. Tor provides a separate circuit for each username+password
// combination.
-tor.isolateCircuitsByDomain = function () {
- mozilla.registerProxyChannelFilter(function (aChannel, aProxy) {
+tor.isolateCircuitsByDomain = function() {
+ mozilla.registerProxyChannelFilter(function(aChannel, aProxy) {
if (!tor.isolationEnabled) {
return aProxy;
}
try {
let channel = aChannel.QueryInterface(Ci.nsIChannel),
- firstPartyDomain = channel.loadInfo.originAttributes.firstPartyDomain;
+ firstPartyDomain = channel.loadInfo.originAttributes.firstPartyDomain;
if (firstPartyDomain === "") {
firstPartyDomain = "--unknown--";
- if (Date.now() - tor.unknownDirtySince > 1000*10*60) {
- logger.eclog(3, "tor catchall circuit has been dirty for over 10 minutes. Rotating.");
+ if (Date.now() - tor.unknownDirtySince > 1000 * 10 * 60) {
+ logger.eclog(
+ 3,
+ "tor catchall circuit has been dirty for over 10 minutes. Rotating."
+ );
tor.newCircuitForDomain("--unknown--");
tor.unknownDirtySince = Date.now();
}
}
- let replacementProxy = tor.socksProxyCredentials(aProxy, firstPartyDomain);
- logger.eclog(3, `tor SOCKS: ${channel.URI.spec} via
- ${replacementProxy.username}:${replacementProxy.password}`);
+ let replacementProxy = tor.socksProxyCredentials(
+ aProxy,
+ firstPartyDomain
+ );
+ logger.eclog(
+ 3,
+ `tor SOCKS: ${channel.URI.spec} via
+ ${replacementProxy.username}:${replacementProxy.password}`
+ );
return replacementProxy;
} catch (e) {
logger.eclog(4, `tor domain isolator error: ${e.message}`);
+ return null;
}
}, 0);
};
@@ -164,7 +184,7 @@ const kMODULE_CID = Components.ID("e33fd6d4-270f-475f-a96f-ff3140279f68");
// DomainIsolator object.
function DomainIsolator() {
- this.wrappedJSObject = this;
+ this.wrappedJSObject = this;
}
// Firefox component requirements
@@ -173,7 +193,7 @@ DomainIsolator.prototype = {
classDescription: kMODULE_NAME,
classID: kMODULE_CID,
contractID: kMODULE_CONTRACTID,
- observe: function (subject, topic, data) {
+ observe(subject, topic, data) {
if (topic === "profile-after-change") {
logger.eclog(3, "domain isolator: set up isolating circuits by domain");
@@ -183,23 +203,23 @@ DomainIsolator.prototype = {
tor.isolateCircuitsByDomain();
}
},
- newCircuitForDomain: function (domain) {
+ newCircuitForDomain(domain) {
tor.newCircuitForDomain(domain);
},
- enableIsolation: function() {
+ enableIsolation() {
tor.isolationEnabled = true;
},
- disableIsolation: function() {
+ disableIsolation() {
tor.isolationEnabled = false;
},
- clearIsolation: function() {
+ clearIsolation() {
tor.clearIsolation();
},
- wrappedJSObject: null
+ wrappedJSObject: null,
};
// Assign factory to global object.
diff --git a/components/dragDropFilter.js b/components/dragDropFilter.js
index 361424d1..4b76bd10 100644
--- a/components/dragDropFilter.js
+++ b/components/dragDropFilter.js
@@ -5,8 +5,9 @@
* access to URLs (a potential proxy bypass vector).
*************************************************************************/
-
-const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+const { XPCOMUtils } = ChromeUtils.import(
+ "resource://gre/modules/XPCOMUtils.jsm"
+);
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetters(this, {
@@ -21,8 +22,9 @@ const kMODULE_CID = Components.ID("f605ec27-d867-44b5-ad97-2a29276642c3");
const kInterfaces = [Ci.nsIObserver, Ci.nsIClassInfo];
function DragDropFilter() {
- this.logger = Cc["@torproject.org/torbutton-logger;1"]
- .getService(Ci.nsISupports).wrappedJSObject;
+ this.logger = Cc["@torproject.org/torbutton-logger;1"].getService(
+ Ci.nsISupports
+ ).wrappedJSObject;
this.logger.log(3, "Component Load 0: New DragDropFilter.");
try {
@@ -32,8 +34,7 @@ function DragDropFilter() {
}
}
-DragDropFilter.prototype =
-{
+DragDropFilter.prototype = {
QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
// make this an nsIClassInfo object
@@ -43,23 +44,25 @@ DragDropFilter.prototype =
classID: kMODULE_CID,
// method of nsIClassInfo
- getInterfaces: function(count) {
+ getInterfaces(count) {
count.value = kInterfaces.length;
return kInterfaces;
},
// method of nsIClassInfo
- getHelperForLanguage: function(count) { return null; },
+ getHelperForLanguage(count) {
+ return null;
+ },
// method of nsIObserver
- observe: function(subject, topic, data) {
- if (topic == "on-datatransfer-available") {
+ observe(subject, topic, data) {
+ if (topic === "on-datatransfer-available") {
this.logger.log(3, "The DataTransfer is available");
- return this.filterDataTransferURLs(subject);
+ this.filterDataTransferURLs(subject);
}
},
- filterDataTransferURLs: function(aDataTransfer) {
+ filterDataTransferURLs(aDataTransfer) {
var types = null;
var type = "";
var count = aDataTransfer.mozItemCount;
@@ -71,16 +74,18 @@ DragDropFilter.prototype =
for (var j = 0; j < len; ++j) {
type = types[j];
this.logger.log(3, "Type is: " + type);
- if (type == "text/x-moz-url" ||
- type == "text/x-moz-url-data" ||
- type == "text/uri-list" ||
- type == "application/x-moz-file-promise-url") {
+ if (
+ type == "text/x-moz-url" ||
+ type == "text/x-moz-url-data" ||
+ type == "text/uri-list" ||
+ type == "application/x-moz-file-promise-url"
+ ) {
aDataTransfer.clearData(type);
this.logger.log(3, "Removing " + type);
}
}
}
- }
+ },
};
// Assign factory to global object.
diff --git a/components/external-app-blocker.js b/components/external-app-blocker.js
index 2fa80d9d..6a53fc01 100644
--- a/components/external-app-blocker.js
+++ b/components/external-app-blocker.js
@@ -12,15 +12,21 @@
* handle an URL (e.g., when the user clicks on a mailto: URL).
*************************************************************************/
-const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+const { XPCOMUtils } = ChromeUtils.import(
+ "resource://gre/modules/XPCOMUtils.jsm"
+);
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-const { PromptUtils } = ChromeUtils.import("resource://gre/modules/SharedPromptUtils.jsm");
+const { PromptUtils } = ChromeUtils.import(
+ "resource://gre/modules/SharedPromptUtils.jsm"
+);
XPCOMUtils.defineLazyModuleGetters(this, {
ComponentUtils: "resource://gre/modules/ComponentUtils.jsm",
});
-let { torbutton_get_property_string } = ChromeUtils.import("resource://torbutton/modules/utils.js", {});
+let { torbutton_get_property_string } = ChromeUtils.import(
+ "resource://torbutton/modules/utils.js"
+);
// Module specific constants
const kMODULE_NAME = "Torbutton External App Handler";
@@ -30,16 +36,19 @@ const kMODULE_CID = Components.ID("3da0269f-fc29-4e9e-a678-c3b1cafcf13f");
const kInterfaces = [Ci.nsIObserver, Ci.nsIClassInfo];
function ExternalAppBlocker() {
- this.logger = Cc["@torproject.org/torbutton-logger;1"]
- .getService(Ci.nsISupports).wrappedJSObject;
+ this.logger = Cc["@torproject.org/torbutton-logger;1"].getService(
+ Ci.nsISupports
+ ).wrappedJSObject;
this.logger.log(3, "Component Load 0: New ExternalAppBlocker.");
}
-ExternalAppBlocker.prototype =
-{
+ExternalAppBlocker.prototype = {
_helperAppLauncher: undefined,
- QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver, Ci.nsIHelperAppWarningDialog]),
+ QueryInterface: ChromeUtils.generateQI([
+ Ci.nsIObserver,
+ Ci.nsIHelperAppWarningDialog,
+ ]),
// make this an nsIClassInfo object
flags: Ci.nsIClassInfo.DOM_OBJECT,
@@ -48,17 +57,18 @@ ExternalAppBlocker.prototype =
classID: kMODULE_CID,
// method of nsIClassInfo
- getInterfaces: function(count) {
+ getInterfaces(count) {
count.value = kInterfaces.length;
return kInterfaces;
},
// method of nsIClassInfo
- getHelperForLanguage: function(count) { return null; },
+ getHelperForLanguage(count) {
+ return null;
+ },
// method of nsIHelperAppWarningDialog
- maybeShow: function(aLauncher, aWindowContext)
- {
+ maybeShow(aLauncher, aWindowContext) {
// Hold a reference to the object that called this component. This is
// important not just because we need to later invoke the
// continueRequest() or cancelRequest() callback on aLauncher, but also
@@ -80,7 +90,7 @@ ExternalAppBlocker.prototype =
* on chrome://global/content/commonDialog.xhtml as well as some of the code
* in resource://gre/modules/SharedPromptUtils.jsm.
*/
- _showPrompt: function(aWindowContext) {
+ _showPrompt(aWindowContext) {
let parentWin;
try {
parentWin = aWindowContext.getInterface(Ci.nsIDOMWindow);
@@ -91,20 +101,22 @@ ExternalAppBlocker.prototype =
let title = torbutton_get_property_string("torbutton.popup.external.title");
let app = torbutton_get_property_string("torbutton.popup.external.app");
let note = torbutton_get_property_string("torbutton.popup.external.note");
- let suggest = torbutton_get_property_string("torbutton.popup.external.suggest");
+ let suggest = torbutton_get_property_string(
+ "torbutton.popup.external.suggest"
+ );
let launch = torbutton_get_property_string("torbutton.popup.launch");
let cancel = torbutton_get_property_string("torbutton.popup.cancel");
let dontask = torbutton_get_property_string("torbutton.popup.dontask");
let args = {
- promptType: "confirmEx",
- title: title,
- text: app+note+suggest+" ",
- checkLabel: dontask,
- checked: false,
- ok: false,
- button0Label: launch,
- button1Label: cancel,
+ promptType: "confirmEx",
+ title,
+ text: app + note + suggest + " ",
+ checkLabel: dontask,
+ checked: false,
+ ok: false,
+ button0Label: launch,
+ button1Label: cancel,
defaultButtonNum: 1, // Cancel
buttonNumClicked: 1, // Cancel
enableDelay: true,
@@ -112,8 +124,13 @@ ExternalAppBlocker.prototype =
let propBag = PromptUtils.objectToPropBag(args);
let uri = "chrome://global/content/commonDialog.xhtml";
- let promptWin = Services.ww.openWindow(parentWin, uri, "_blank",
- "centerscreen,chrome,titlebar", propBag);
+ let promptWin = Services.ww.openWindow(
+ parentWin,
+ uri,
+ "_blank",
+ "centerscreen,chrome,titlebar",
+ propBag
+ );
promptWin.addEventListener("load", aEvent => {
promptWin.addEventListener("unload", aEvent => {
PromptUtils.propBagToObject(propBag, args);
@@ -122,16 +139,18 @@ ExternalAppBlocker.prototype =
// Save the checkbox value and tell the browser's external helper app
// module about the user's choice.
if (args.checked) {
- Services.prefs.setBoolPref("extensions.torbutton.launch_warning",
- false);
+ Services.prefs.setBoolPref(
+ "extensions.torbutton.launch_warning",
+ false
+ );
}
this._helperAppLauncher.continueRequest();
} else {
this._helperAppLauncher.cancelRequest(Cr.NS_BINDING_ABORTED);
}
- }, false);
- }, false);
+ });
+ });
},
};
diff --git a/components/startup-observer.js b/components/startup-observer.js
index 164c9219..77df172a 100644
--- a/components/startup-observer.js
+++ b/components/startup-observer.js
@@ -13,7 +13,9 @@
*************************************************************************/
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+const { XPCOMUtils } = ChromeUtils.import(
+ "resource://gre/modules/XPCOMUtils.jsm"
+);
XPCOMUtils.defineLazyModuleGetters(this, {
ComponentUtils: "resource://gre/modules/ComponentUtils.jsm",
@@ -47,155 +49,163 @@ function cleanupCookies() {
}
function StartupObserver() {
- this.logger = Cc["@torproject.org/torbutton-logger;1"]
- .getService(Ci.nsISupports).wrappedJSObject;
- this._prefs = Services.prefs;
- this.logger.log(3, "Startup Observer created");
-
- var env = Cc["@mozilla.org/process/environment;1"]
- .getService(Ci.nsIEnvironment);
- var prefName = "browser.startup.homepage";
- if (env.exists("TOR_DEFAULT_HOMEPAGE")) {
- // if the user has set this value in a previous installation, don't override it
- if (!this._prefs.prefHasUserValue(prefName)) {
- this._prefs.setCharPref(prefName, env.get("TOR_DEFAULT_HOMEPAGE"));
- }
- }
-
- try {
- var test = this._prefs.getCharPref("torbrowser.version");
- this.is_tbb = true;
- this.logger.log(3, "This is a Tor Browser's XPCOM");
- } catch(e) {
- this.logger.log(3, "This is not a Tor Browser's XPCOM");
- }
-
- try {
- // XXX: We're in a race with HTTPS-Everywhere to update our proxy settings
- // before the initial SSL-Observatory test... If we lose the race, Firefox
- // caches the old proxy settings for check.tp.o somehwere, and it never loads :(
- this.setProxySettings();
- } catch(e) {
- this.logger.log(4, "Early proxy change failed. Will try again at profile load. Error: "+e);
+ this.logger = Cc["@torproject.org/torbutton-logger;1"].getService(
+ Ci.nsISupports
+ ).wrappedJSObject;
+ this._prefs = Services.prefs;
+ this.logger.log(3, "Startup Observer created");
+
+ var env = Cc["@mozilla.org/process/environment;1"].getService(
+ Ci.nsIEnvironment
+ );
+ var prefName = "browser.startup.homepage";
+ if (env.exists("TOR_DEFAULT_HOMEPAGE")) {
+ // if the user has set this value in a previous installation, don't override it
+ if (!this._prefs.prefHasUserValue(prefName)) {
+ this._prefs.setCharPref(prefName, env.get("TOR_DEFAULT_HOMEPAGE"));
}
+ }
- cleanupCookies();
-
- // Using all possible locales so that we do not have to change this list every time we support
- // a new one.
- const allLocales = [
- "en-US", "ach", "af", "an", "ar", "ast", "az", "be", "bg", "bn", "br", "bs", "ca", "cak",
- "crh", "cs", "cy", "da", "de", "dsb", "el", "en-CA", "en-GB", "eo", "es-AR", "es-CL",
- "es-ES", "es-MX", "et", "eu", "fa", "ff", "fi", "fr", "fy-NL", "ga-IE", "gd", "gl", "gn",
- "gu-IN", "he", "hi-IN", "hr", "hsb", "hu", "hy-AM", "ia", "id", "is", "it", "ja",
- "ja-JP-mac", "ka", "kab", "kk", "km", "kn", "ko", "lij", "lo", "lt", "ltg", "lv", "mk", "mr",
- "ms", "my", "nb-NO", "ne-NP", "nl", "nn-NO", "oc", "pa-IN", "pl", "pt-BR", "pt-PT", "rm",
- "ro", "ru", "si", "sk", "sl", "son", "sq", "sr", "sv-SE", "ta", "te", "th", "tl", "tr",
- "trs", "uk", "ur", "uz", "vi", "wo", "xh", "zh-CN", "zh-TW"
- ];
- let torSource = new FileSource(
- "torbutton",
- allLocales,
- "resource://torbutton/locale/{locale}/",
- true, // skip this FileSource locales when computing Services.locale.availableLocales
+ this.is_tbb = true;
+
+ try {
+ // XXX: We're in a race with HTTPS-Everywhere to update our proxy settings
+ // before the initial SSL-Observatory test... If we lose the race, Firefox
+ // caches the old proxy settings for check.tp.o somehwere, and it never loads :(
+ this.setProxySettings();
+ } catch (e) {
+ this.logger.log(
+ 4,
+ "Early proxy change failed. Will try again at profile load. Error: " + e
);
- if (L10nRegistry.registerSources) {
- L10nRegistry.registerSources([torSource]);
- } else {
- L10nRegistry.registerSource(torSource);
- }
+ }
+
+ cleanupCookies();
+
+ // Using all possible locales so that we do not have to change this list every time we support
+ // a new one.
+ /* eslint-disable */
+ const allLocales = [
+ "en-US", "ach", "af", "an", "ar", "ast", "az", "be", "bg", "bn", "br", "bs", "ca", "cak",
+ "crh", "cs", "cy", "da", "de", "dsb", "el", "en-CA", "en-GB", "eo", "es-AR", "es-CL",
+ "es-ES", "es-MX", "et", "eu", "fa", "ff", "fi", "fr", "fy-NL", "ga-IE", "gd", "gl", "gn",
+ "gu-IN", "he", "hi-IN", "hr", "hsb", "hu", "hy-AM", "ia", "id", "is", "it", "ja",
+ "ja-JP-mac", "ka", "kab", "kk", "km", "kn", "ko", "lij", "lo", "lt", "ltg", "lv", "mk", "mr",
+ "ms", "my", "nb-NO", "ne-NP", "nl", "nn-NO", "oc", "pa-IN", "pl", "pt-BR", "pt-PT", "rm",
+ "ro", "ru", "si", "sk", "sl", "son", "sq", "sr", "sv-SE", "ta", "te", "th", "tl", "tr",
+ "trs", "uk", "ur", "uz", "vi", "wo", "xh", "zh-CN", "zh-TW"
+ ];
+ /* eslint-enable */
+ let torSource = new FileSource(
+ "torbutton",
+ allLocales,
+ "resource://torbutton/locale/{locale}/",
+ true // skip this FileSource locales when computing Services.locale.availableLocales
+ );
+ if (L10nRegistry.registerSources) {
+ L10nRegistry.registerSources([torSource]);
+ } else {
+ L10nRegistry.registerSource(torSource);
+ }
}
StartupObserver.prototype = {
- // Bug 6803: We need to get the env vars early due to
- // some weird proxy caching code that showed up in FF15.
- // Otherwise, homepage domain loads fail forever.
- setProxySettings: function() {
- if (!this.is_tbb)
- return;
-
- // Bug 1506: Still want to get these env vars
- let environ = Cc["@mozilla.org/process/environment;1"]
- .getService(Ci.nsIEnvironment);
- if (environ.exists("TOR_TRANSPROXY")) {
- this.logger.log(3, "Resetting Tor settings to transproxy");
- this._prefs.setBoolPref("network.proxy.socks_remote_dns", false);
- this._prefs.setIntPref("network.proxy.type", 0);
- this._prefs.setIntPref("network.proxy.socks_port", 0);
- this._prefs.setCharPref("network.proxy.socks", "");
- } else {
- // Try to retrieve SOCKS proxy settings from Tor Launcher.
- let socksPortInfo;
- try {
- let tlps = Cc["@torproject.org/torlauncher-protocol-service;1"]
- .getService(Ci.nsISupports).wrappedJSObject;
- socksPortInfo = tlps.TorGetSOCKSPortInfo();
- } catch(e) {
- this.logger.log(3, "tor launcher failed " + e);
- }
+ // Bug 6803: We need to get the env vars early due to
+ // some weird proxy caching code that showed up in FF15.
+ // Otherwise, homepage domain loads fail forever.
+ setProxySettings() {
+ if (!this.is_tbb) {
+ return;
+ }
- // If Tor Launcher is not available, check environment variables.
- if (!socksPortInfo) {
- socksPortInfo = { ipcFile: undefined, host: undefined, port: 0 };
+ // Bug 1506: Still want to get these env vars
+ let environ = Cc["@mozilla.org/process/environment;1"].getService(
+ Ci.nsIEnvironment
+ );
+ if (environ.exists("TOR_TRANSPROXY")) {
+ this.logger.log(3, "Resetting Tor settings to transproxy");
+ this._prefs.setBoolPref("network.proxy.socks_remote_dns", false);
+ this._prefs.setIntPref("network.proxy.type", 0);
+ this._prefs.setIntPref("network.proxy.socks_port", 0);
+ this._prefs.setCharPref("network.proxy.socks", "");
+ } else {
+ // Try to retrieve SOCKS proxy settings from Tor Launcher.
+ let socksPortInfo;
+ try {
+ let tlps = Cc[
+ "@torproject.org/torlauncher-protocol-service;1"
+ ].getService(Ci.nsISupports).wrappedJSObject;
+ socksPortInfo = tlps.TorGetSOCKSPortInfo();
+ } catch (e) {
+ this.logger.log(3, "tor launcher failed " + e);
+ }
- let isWindows = Services.appinfo.OS === "WINNT";
- if (!isWindows && environ.exists("TOR_SOCKS_IPC_PATH")) {
- socksPortInfo.ipcFile = new FileUtils.File(
- environ.get("TOR_SOCKS_IPC_PATH"));
- }
- else
- {
- if (environ.exists("TOR_SOCKS_HOST"))
- socksPortInfo.host = environ.get("TOR_SOCKS_HOST");
- if (environ.exists("TOR_SOCKS_PORT"))
- socksPortInfo.port = parseInt(environ.get("TOR_SOCKS_PORT"));
- }
- }
+ // If Tor Launcher is not available, check environment variables.
+ if (!socksPortInfo) {
+ socksPortInfo = { ipcFile: undefined, host: undefined, port: 0 };
- // Adjust network.proxy prefs.
- if (socksPortInfo.ipcFile) {
- let fph = Services.io.getProtocolHandler("file")
- .QueryInterface(Ci.nsIFileProtocolHandler);
- let fileURI = fph.newFileURI(socksPortInfo.ipcFile);
- this.logger.log(3, "Reset socks to "+fileURI.spec);
- this._prefs.setCharPref("network.proxy.socks", fileURI.spec);
- this._prefs.setIntPref("network.proxy.socks_port", 0);
+ let isWindows = Services.appinfo.OS === "WINNT";
+ if (!isWindows && environ.exists("TOR_SOCKS_IPC_PATH")) {
+ socksPortInfo.ipcFile = new FileUtils.File(
+ environ.get("TOR_SOCKS_IPC_PATH")
+ );
} else {
- if (socksPortInfo.host) {
- this._prefs.setCharPref("network.proxy.socks", socksPortInfo.host);
- this.logger.log(3, "Reset socks host to "+socksPortInfo.host);
+ if (environ.exists("TOR_SOCKS_HOST")) {
+ socksPortInfo.host = environ.get("TOR_SOCKS_HOST");
}
- if (socksPortInfo.port) {
- this._prefs.setIntPref("network.proxy.socks_port",
- socksPortInfo.port);
- this.logger.log(3, "Reset socks port to "+socksPortInfo.port);
+ if (environ.exists("TOR_SOCKS_PORT")) {
+ socksPortInfo.port = parseInt(environ.get("TOR_SOCKS_PORT"));
}
}
+ }
- if (socksPortInfo.ipcFile || socksPortInfo.host || socksPortInfo.port) {
- this._prefs.setBoolPref("network.proxy.socks_remote_dns", true);
- this._prefs.setIntPref("network.proxy.type", 1);
+ // Adjust network.proxy prefs.
+ if (socksPortInfo.ipcFile) {
+ let fph = Services.io
+ .getProtocolHandler("file")
+ .QueryInterface(Ci.nsIFileProtocolHandler);
+ let fileURI = fph.newFileURI(socksPortInfo.ipcFile);
+ this.logger.log(3, "Reset socks to " + fileURI.spec);
+ this._prefs.setCharPref("network.proxy.socks", fileURI.spec);
+ this._prefs.setIntPref("network.proxy.socks_port", 0);
+ } else {
+ if (socksPortInfo.host) {
+ this._prefs.setCharPref("network.proxy.socks", socksPortInfo.host);
+ this.logger.log(3, "Reset socks host to " + socksPortInfo.host);
+ }
+ if (socksPortInfo.port) {
+ this._prefs.setIntPref(
+ "network.proxy.socks_port",
+ socksPortInfo.port
+ );
+ this.logger.log(3, "Reset socks port to " + socksPortInfo.port);
}
}
- // Force prefs to be synced to disk
- Services.prefs.savePrefFile(null);
+ if (socksPortInfo.ipcFile || socksPortInfo.host || socksPortInfo.port) {
+ this._prefs.setBoolPref("network.proxy.socks_remote_dns", true);
+ this._prefs.setIntPref("network.proxy.type", 1);
+ }
+ }
+
+ // Force prefs to be synced to disk
+ Services.prefs.savePrefFile(null);
- this.logger.log(3, "Synced network settings to environment.");
- },
+ this.logger.log(3, "Synced network settings to environment.");
+ },
- observe: function(subject, topic, data) {
- if(topic == "profile-after-change") {
- // Bug 1506 P1: We listen to these prefs as signals for startup,
- // but only for hackish reasons.
- this._prefs.setBoolPref("extensions.torbutton.startup", true);
+ observe(subject, topic, data) {
+ if (topic == "profile-after-change") {
+ // Bug 1506 P1: We listen to these prefs as signals for startup,
+ // but only for hackish reasons.
+ this._prefs.setBoolPref("extensions.torbutton.startup", true);
- this.setProxySettings();
- }
+ this.setProxySettings();
+ }
- // In all cases, force prefs to be synced to disk
- Services.prefs.savePrefFile(null);
- },
+ // In all cases, force prefs to be synced to disk
+ Services.prefs.savePrefFile(null);
+ },
QueryInterface: ChromeUtils.generateQI([Ci.nsIClassInfo]),
@@ -205,7 +215,7 @@ StartupObserver.prototype = {
contractID: kMODULE_CONTRACTID,
// Hack to get us registered early to observe recovery
- _xpcom_categories: [{category:"profile-after-change"}],
+ _xpcom_categories: [{ category: "profile-after-change" }],
};
// Assign factory to global object.
diff --git a/components/torCheckService.js b/components/torCheckService.js
index 07b1aa99..41d716ff 100644
--- a/components/torCheckService.js
+++ b/components/torCheckService.js
@@ -3,12 +3,14 @@
* See LICENSE for licensing information.
*
* vim: set sw=2 sts=2 ts=8 et syntax=javascript:
- *
+ *
* Tor check service
*************************************************************************/
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+const { XPCOMUtils } = ChromeUtils.import(
+ "resource://gre/modules/XPCOMUtils.jsm"
+);
XPCOMUtils.defineLazyModuleGetters(this, {
ComponentUtils: "resource://gre/modules/ComponentUtils.jsm",
@@ -20,16 +22,16 @@ const kMODULE_CONTRACTID = "@torproject.org/torbutton-torCheckService;1";
const kMODULE_CID = Components.ID("5d57312b-5d8c-4169-b4af-e80d6a28a72e");
function TBTorCheckService() {
- this._logger = Cc["@torproject.org/torbutton-logger;1"]
- .getService(Ci.nsISupports).wrappedJSObject;
+ this._logger = Cc["@torproject.org/torbutton-logger;1"].getService(
+ Ci.nsISupports
+ ).wrappedJSObject;
this._logger.log(3, "Torbutton Tor Check Service initialized");
this._statusOfTorCheck = this.kCheckNotInitiated;
this.wrappedJSObject = this;
}
-TBTorCheckService.prototype =
-{
+TBTorCheckService.prototype = {
QueryInterface: ChromeUtils.generateQI([Ci.nsIClassInfo]),
kCheckNotInitiated: 0, // Possible values for statusOfTorCheck.
@@ -49,87 +51,84 @@ TBTorCheckService.prototype =
contractID: kMODULE_CONTRACTID,
// method of nsIClassInfo
- getInterfaces: function(count) {
+ getInterfaces(count) {
var interfaceList = [Ci.nsIClassInfo];
count.value = interfaceList.length;
return interfaceList;
},
// method of nsIClassInfo
- getHelperForLanguage: function(count) { return null; },
+ getHelperForLanguage(count) {
+ return null;
+ },
// Public methods.
- get statusOfTorCheck()
- {
+ get statusOfTorCheck() {
return this._statusOfTorCheck;
},
- set statusOfTorCheck(aStatus)
- {
+ set statusOfTorCheck(aStatus) {
this._statusOfTorCheck = aStatus;
},
- createCheckRequest: function(aAsync)
- {
- Cu.importGlobalProperties(["XMLHttpRequest"]);
+ createCheckRequest(aAsync) {
let req = new XMLHttpRequest();
let url = Services.prefs.getCharPref("extensions.torbutton.test_url");
req.open("GET", url, aAsync);
req.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
req.overrideMimeType("text/xml");
- req.timeout = 120000; // Wait at most two minutes for a response.
+ req.timeout = 120000; // Wait at most two minutes for a response.
return req;
},
- parseCheckResponse: function(aReq)
- {
+ parseCheckResponse(aReq) {
let ret = 0;
- if(aReq.status == 200) {
- if(!aReq.responseXML) {
- this._logger.log(5, "Check failed! Not text/xml!");
- ret = 1;
- } else {
- let result = aReq.responseXML.getElementById('TorCheckResult');
-
- if(result===null) {
- this._logger.log(5, "Test failed! No TorCheckResult element");
- ret = 2;
- } else if(typeof(result.target) == 'undefined'
- || result.target === null) {
- this._logger.log(5, "Test failed! No target");
- ret = 3;
- } else if(result.target === "success") {
- this._logger.log(3, "Test Successful");
- ret = 4;
- } else if(result.target === "failure") {
- this._logger.log(5, "Tor test failed!");
- ret = 5;
- } else if(result.target === "unknown") {
- this._logger.log(5, "Tor test failed. TorDNSEL Failure?");
- ret = 6;
- } else {
- this._logger.log(5, "Tor test failed. Strange target.");
- ret = 7;
- }
- }
+ if (aReq.status == 200) {
+ if (!aReq.responseXML) {
+ this._logger.log(5, "Check failed! Not text/xml!");
+ ret = 1;
} else {
- if (0 == aReq.status) {
- try {
- var req = aReq.channel.QueryInterface(Ci.nsIRequest);
- if (req.status == Cr.NS_ERROR_PROXY_CONNECTION_REFUSED)
- {
- this._logger.log(5, "Tor test failed. Proxy connection refused");
- ret = 8;
- }
- } catch (e) {}
+ let result = aReq.responseXML.getElementById("TorCheckResult");
+
+ if (result === null) {
+ this._logger.log(5, "Test failed! No TorCheckResult element");
+ ret = 2;
+ } else if (
+ typeof result.target == "undefined" ||
+ result.target === null
+ ) {
+ this._logger.log(5, "Test failed! No target");
+ ret = 3;
+ } else if (result.target === "success") {
+ this._logger.log(3, "Test Successful");
+ ret = 4;
+ } else if (result.target === "failure") {
+ this._logger.log(5, "Tor test failed!");
+ ret = 5;
+ } else if (result.target === "unknown") {
+ this._logger.log(5, "Tor test failed. TorDNSEL Failure?");
+ ret = 6;
+ } else {
+ this._logger.log(5, "Tor test failed. Strange target.");
+ ret = 7;
}
+ }
+ } else {
+ if (0 == aReq.status) {
+ try {
+ var req = aReq.channel.QueryInterface(Ci.nsIRequest);
+ if (req.status == Cr.NS_ERROR_PROXY_CONNECTION_REFUSED) {
+ this._logger.log(5, "Tor test failed. Proxy connection refused");
+ ret = 8;
+ }
+ } catch (e) {}
+ }
- if (ret == 0)
- {
- this._logger.log(5, "Tor test failed. HTTP Error: "+aReq.status);
- ret = -aReq.status;
- }
+ if (ret == 0) {
+ this._logger.log(5, "Tor test failed. HTTP Error: " + aReq.status);
+ ret = -aReq.status;
}
+ }
return ret;
},
diff --git a/components/torbutton-logger.js b/components/torbutton-logger.js
index d80d13c4..2fdcd7e6 100644
--- a/components/torbutton-logger.js
+++ b/components/torbutton-logger.js
@@ -14,31 +14,34 @@ const kMODULE_CONTRACTID = "@torproject.org/torbutton-logger;1";
const kMODULE_CID = Components.ID("f36d72c9-9718-4134-b550-e109638331d7");
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+const { XPCOMUtils } = ChromeUtils.import(
+ "resource://gre/modules/XPCOMUtils.jsm"
+);
XPCOMUtils.defineLazyModuleGetters(this, {
ComponentUtils: "resource://gre/modules/ComponentUtils.jsm",
});
function TorbuttonLogger() {
- // Register observer
- Services.prefs.addObserver("extensions.torbutton", this);
-
- this.loglevel = Services.prefs.getIntPref("extensions.torbutton.loglevel");
- this.logmethod = Services.prefs.getIntPref("extensions.torbutton.logmethod");
-
- try {
- var logMngr = Cc["@mozmonkey.com/debuglogger/manager;1"]
- .getService(Ci.nsIDebugLoggerManager);
- this._debuglog = logMngr.registerLogger("torbutton");
- } catch (exErr) {
- this._debuglog = false;
- }
- this._console = Services.console;
+ // Register observer
+ Services.prefs.addObserver("extensions.torbutton", this);
+
+ this.loglevel = Services.prefs.getIntPref("extensions.torbutton.loglevel");
+ this.logmethod = Services.prefs.getIntPref("extensions.torbutton.logmethod");
+
+ try {
+ var logMngr = Cc["@mozmonkey.com/debuglogger/manager;1"].getService(
+ Ci.nsIDebugLoggerManager
+ );
+ this._debuglog = logMngr.registerLogger("torbutton");
+ } catch (exErr) {
+ this._debuglog = false;
+ }
+ this._console = Services.console;
- // This JSObject is exported directly to chrome
- this.wrappedJSObject = this;
- this.log(3, "Torbutton debug output ready");
+ // This JSObject is exported directly to chrome
+ this.wrappedJSObject = this;
+ this.log(3, "Torbutton debug output ready");
}
/**
@@ -49,18 +52,16 @@ function TorbuttonLogger() {
const nsIClassInfo = Ci.nsIClassInfo;
-const logString = { 1:"VERB", 2:"DBUG", 3: "INFO", 4:"NOTE", 5:"WARN" };
+const logString = { 1: "VERB", 2: "DBUG", 3: "INFO", 4: "NOTE", 5: "WARN" };
-function padInt(i)
-{
- return (i < 10) ? '0' + i : i;
+function padInt(i) {
+ return i < 10 ? "0" + i : i;
}
-TorbuttonLogger.prototype =
-{
+TorbuttonLogger.prototype = {
QueryInterface: ChromeUtils.generateQI([Ci.nsIClassInfo]),
- wrappedJSObject: null, // Initialized by constructor
+ wrappedJSObject: null, // Initialized by constructor
// make this an nsIClassInfo object
flags: nsIClassInfo.DOM_OBJECT,
@@ -71,62 +72,78 @@ TorbuttonLogger.prototype =
contractID: kMODULE_CONTRACTID,
// method of nsIClassInfo
- getInterfaces: function(count) {
+ getInterfaces(count) {
var interfaceList = [nsIClassInfo];
count.value = interfaceList.length;
return interfaceList;
},
// method of nsIClassInfo
- getHelperForLanguage: function(count) { return null; },
+ getHelperForLanguage(count) {
+ return null;
+ },
- formatLog: function(str, level) {
- var d = new Date();
- var now = padInt(d.getUTCMonth()+1)+"-"+padInt(d.getUTCDate())+" "+padInt(d.getUTCHours())+":"+padInt(d.getUTCMinutes())+":"+padInt(d.getUTCSeconds());
- return "["+now+"] Torbutton "+logString[level]+": "+str;
+ formatLog(str, level) {
+ var d = new Date();
+ var now =
+ padInt(d.getUTCMonth() + 1) +
+ "-" +
+ padInt(d.getUTCDate()) +
+ " " +
+ padInt(d.getUTCHours()) +
+ ":" +
+ padInt(d.getUTCMinutes()) +
+ ":" +
+ padInt(d.getUTCSeconds());
+ return "[" + now + "] Torbutton " + logString[level] + ": " + str;
},
// error console log
- eclog: function(level, str) {
- switch(this.logmethod) {
- case 0: // stderr
- if(this.loglevel <= level)
- dump(this.formatLog(str, level)+"\n");
- break;
- default: // errorconsole
- if(this.loglevel <= level)
- this._console.logStringMessage(this.formatLog(str,level));
- break;
- }
+ eclog(level, str) {
+ switch (this.logmethod) {
+ case 0: // stderr
+ if (this.loglevel <= level) {
+ dump(this.formatLog(str, level) + "\n");
+ }
+ break;
+ default:
+ // errorconsole
+ if (this.loglevel <= level) {
+ this._console.logStringMessage(this.formatLog(str, level));
+ }
+ break;
+ }
},
- safe_log: function(level, str, scrub) {
- if (this.loglevel < 4) {
- this.eclog(level, str+scrub);
- } else {
- this.eclog(level, str+" [scrubbed]");
- }
+ safe_log(level, str, scrub) {
+ if (this.loglevel < 4) {
+ this.eclog(level, str + scrub);
+ } else {
+ this.eclog(level, str + " [scrubbed]");
+ }
},
- log: function(level, str) {
- switch(this.logmethod) {
- case 2: // debuglogger
- if(this._debuglog) {
- this._debuglog.log((6-level), this.formatLog(str,level));
- break;
- }
- // fallthrough
- case 0: // stderr
- if(this.loglevel <= level)
- dump(this.formatLog(str,level)+"\n");
- break;
- default:
- dump("Bad log method: "+this.logmethod);
- case 1: // errorconsole
- if(this.loglevel <= level)
- this._console.logStringMessage(this.formatLog(str,level));
- break;
- }
+ log(level, str) {
+ switch (this.logmethod) {
+ case 2: // debuglogger
+ if (this._debuglog) {
+ this._debuglog.log(6 - level, this.formatLog(str, level));
+ break;
+ }
+ // fallthrough
+ case 0: // stderr
+ if (this.loglevel <= level) {
+ dump(this.formatLog(str, level) + "\n");
+ }
+ break;
+ case 1: // errorconsole
+ if (this.loglevel <= level) {
+ this._console.logStringMessage(this.formatLog(str, level));
+ }
+ break;
+ default:
+ dump("Bad log method: " + this.logmethod);
+ }
},
// Pref observer interface implementation
@@ -134,29 +151,33 @@ TorbuttonLogger.prototype =
// topic: what event occurred
// subject: what nsIPrefBranch we're observing
// data: which pref has been changed (relative to subject)
- observe: function(subject, topic, data)
- {
- if (topic != "nsPref:changed") return;
- switch (data) {
- case "extensions.torbutton.logmethod":
- this.logmethod = Services.prefs.getIntPref("extensions.torbutton.logmethod");
- if (this.logmethod === 0) {
- Services.prefs.setBoolPref("browser.dom.window.dump.enabled",
- true);
- } else if (Services.prefs.
- getIntPref("extensions.torlauncher.logmethod", 3) !== 0) {
- // If Tor Launcher is not available or its log method is not 0
- // then let's reset the dump pref.
- Services.prefs.setBoolPref("browser.dom.window.dump.enabled",
- false);
- }
- break;
- case "extensions.torbutton.loglevel":
- this.loglevel = Services.prefs.getIntPref("extensions.torbutton.loglevel");
- break;
- }
- }
-}
+ observe(subject, topic, data) {
+ if (topic != "nsPref:changed") {
+ return;
+ }
+ switch (data) {
+ case "extensions.torbutton.logmethod":
+ this.logmethod = Services.prefs.getIntPref(
+ "extensions.torbutton.logmethod"
+ );
+ if (this.logmethod === 0) {
+ Services.prefs.setBoolPref("browser.dom.window.dump.enabled", true);
+ } else if (
+ Services.prefs.getIntPref("extensions.torlauncher.logmethod", 3) !== 0
+ ) {
+ // If Tor Launcher is not available or its log method is not 0
+ // then let's reset the dump pref.
+ Services.prefs.setBoolPref("browser.dom.window.dump.enabled", false);
+ }
+ break;
+ case "extensions.torbutton.loglevel":
+ this.loglevel = Services.prefs.getIntPref(
+ "extensions.torbutton.loglevel"
+ );
+ break;
+ }
+ },
+};
// Assign factory to global object.
const NSGetFactory = XPCOMUtils.generateNSGetFactory
diff --git a/modules/tor-control-port.js b/modules/tor-control-port.js
index 51ac8ac0..dc59c8da 100644
--- a/modules/tor-control-port.js
+++ b/modules/tor-control-port.js
@@ -20,27 +20,24 @@
/* jshint esnext: true */
/* jshint -W097 */
-/* global Components, console, Services */
+/* global console */
"use strict";
-// ### Mozilla Abbreviations
-let { Constructor: CC } = Components;
-
// ### Import Mozilla Services
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const { TorProtocolService, TorProcessStatus } = ChromeUtils.import(
- "resource:///modules/TorProtocolService.jsm"
+ "resource:///modules/TorProtocolService.jsm"
);
// tor-launcher observer topics
const TorTopics = Object.freeze({
- ProcessIsReady: "TorProcessIsReady",
+ ProcessIsReady: "TorProcessIsReady",
});
// __log__.
// Logging function
-let logger = Cc["@torproject.org/torbutton-logger;1"]
- .getService(Ci.nsISupports).wrappedJSObject;
+let logger = Cc["@torproject.org/torbutton-logger;1"].getService(Ci.nsISupports)
+ .wrappedJSObject;
let log = x => logger.eclog(3, x.trimRight().replace(/\r\n/g, "\n"));
// ### announce this file
@@ -48,19 +45,26 @@ log("Loading tor-control-port.js\n");
class AsyncSocket {
constructor(ipcFile, host, port) {
- let sts = Cc["@mozilla.org/network/socket-transport-service;1"].getService(Ci.nsISocketTransportService);
+ let sts = Cc["@mozilla.org/network/socket-transport-service;1"].getService(
+ Ci.nsISocketTransportService
+ );
const OPEN_UNBUFFERED = Ci.nsITransport.OPEN_UNBUFFERED;
- let socketTransport = ipcFile ?
- sts.createUnixDomainTransport(ipcFile) :
- sts.createTransport([], host, port, null, null);
-
+ let socketTransport = ipcFile
+ ? sts.createUnixDomainTransport(ipcFile)
+ : sts.createTransport([], host, port, null, null);
- this.outputStream = socketTransport.openOutputStream(OPEN_UNBUFFERED, 1, 1).QueryInterface(Ci.nsIAsyncOutputStream);
+ this.outputStream = socketTransport
+ .openOutputStream(OPEN_UNBUFFERED, 1, 1)
+ .QueryInterface(Ci.nsIAsyncOutputStream);
this.outputQueue = [];
- this.inputStream = socketTransport.openInputStream(OPEN_UNBUFFERED, 1, 1).QueryInterface(Ci.nsIAsyncInputStream);
- this.scriptableInputStream = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(Ci.nsIScriptableInputStream);
+ this.inputStream = socketTransport
+ .openInputStream(OPEN_UNBUFFERED, 1, 1)
+ .QueryInterface(Ci.nsIAsyncInputStream);
+ this.scriptableInputStream = Cc[
+ "@mozilla.org/scriptableinputstream;1"
+ ].createInstance(Ci.nsIScriptableInputStream);
this.scriptableInputStream.init(this.inputStream);
this.inputQueue = [];
}
@@ -68,13 +72,15 @@ class AsyncSocket {
// asynchronously write string to underlying socket and return number of bytes written
async write(str) {
return new Promise((resolve, reject) => {
-
// asyncWait next write request
const tryAsyncWait = () => {
- if (this.outputQueue.length > 0) {
+ if (this.outputQueue.length) {
this.outputStream.asyncWait(
this.outputQueue.at(0), // next request
- 0, 0, Services.tm.currentThread);
+ 0,
+ 0,
+ Services.tm.currentThread
+ );
}
};
@@ -98,7 +104,7 @@ class AsyncSocket {
// reject promise on error
reject(err);
}
- }
+ },
});
// length 1 imples that there is no in-flight asyncWait, so we may immediately
@@ -112,20 +118,24 @@ class AsyncSocket {
// asynchronously read string from underlying socket and return it
async read() {
return new Promise((resolve, reject) => {
-
const tryAsyncWait = () => {
- if (this.inputQueue.length > 0) {
+ if (this.inputQueue.length) {
this.inputStream.asyncWait(
- this.inputQueue.at(0), // next input request
- 0, 0, Services.tm.currentThread);
+ this.inputQueue.at(0), // next input request
+ 0,
+ 0,
+ Services.tm.currentThread
+ );
}
};
this.inputQueue.push({
- onInputStreamReady: (stream) => {
+ onInputStreamReady: stream => {
try {
// read our string from input stream
- let str = this.scriptableInputStream.read(this.scriptableInputStream.available());
+ let str = this.scriptableInputStream.read(
+ this.scriptableInputStream.available()
+ );
// remove this callback object from queue now that we have read
this.inputQueue.shift();
@@ -138,7 +148,7 @@ class AsyncSocket {
} catch (err) {
reject(err);
}
- }
+ },
});
// length 1 imples that there is no in-flight asyncWait, so we may immediately
@@ -153,7 +163,7 @@ class AsyncSocket {
this.outputStream.close();
this.inputStream.close();
}
-};
+}
class ControlSocket {
constructor(asyncSocket) {
@@ -165,9 +175,15 @@ class ControlSocket {
this.mainDispatcher = io.callbackDispatcher();
this.notificationDispatcher = io.callbackDispatcher();
// mainDispatcher pushes only async notifications (650) to notificationDispatcher
- this.mainDispatcher.addCallback(/^650/, this._handleNotification.bind(this));
+ this.mainDispatcher.addCallback(
+ /^650/,
+ this._handleNotification.bind(this)
+ );
// callback for handling responses and errors
- this.mainDispatcher.addCallback(/^[245]\d\d/, this._handleCommandReply.bind(this) );
+ this.mainDispatcher.addCallback(
+ /^[245]\d\d/,
+ this._handleCommandReply.bind(this)
+ );
this.commandQueue = [];
@@ -178,7 +194,7 @@ class ControlSocket {
// immediately returns next line in queue (pendingLines) if present
async _readLine() {
// keep reading from socket until we have a full line to return
- while(this.pendingLines.length == 0) {
+ while (!this.pendingLines.length) {
// read data from our socket and spit on newline tokens
this.pendingData += await this.socket.read();
let lines = this.pendingData.split("\r\n");
@@ -189,7 +205,6 @@ class ControlSocket {
// copy remaining full lines to our pendingLines list
this.pendingLines = this.pendingLines.concat(lines);
-
}
return this.pendingLines.shift();
}
@@ -216,23 +231,24 @@ class ControlSocket {
// and waiting for a terminating "." on its own line.
// (See control-spec section 3.9 and https://trac.torproject.org/16990#comment:28
// Ensure this is the first line of a new message
+ // eslint-disable-next-line no-lonely-if
if (message.length === 1 && line.match(/^\d\d\d\+.+?=$/)) {
handlingMultlineValue = true;
}
// look for end of message (note the space character at end of the regex)
- else if(line.match(/^\d\d\d /)) {
+ else if (line.match(/^\d\d\d /)) {
if (message.length == 1) {
endOfMessageFound = true;
} else {
- let firstReplyCode = message[0].substring(0,3);
- let lastReplyCode = line.substring(0,3);
+ let firstReplyCode = message[0].substring(0, 3);
+ let lastReplyCode = line.substring(0, 3);
if (firstReplyCode == lastReplyCode) {
endOfMessageFound = true;
}
}
}
}
- } while(!endOfMessageFound);
+ } while (!endOfMessageFound);
// join our lines back together to form one message
return message.join("\r\n");
@@ -240,14 +256,14 @@ class ControlSocket {
async _startMessagePump() {
try {
- while(true) {
+ while (true) {
let message = await this._readMessage();
log("controlPort >> " + message);
this.mainDispatcher.pushMessage(message);
}
} catch (err) {
this._isOpen = false;
- for(const cmd of this.commandQueue) {
+ for (const cmd of this.commandQueue) {
cmd.reject(err);
}
this.commandQueue = [];
@@ -269,9 +285,9 @@ class ControlSocket {
// in _startMessagePump (on stream error)
return new Promise((resolve, reject) => {
let command = {
- commandString: commandString,
- resolve: resolve,
- reject: reject,
+ commandString,
+ resolve,
+ reject,
};
this.commandQueue.push(command);
@@ -288,7 +304,7 @@ class ControlSocket {
} else if (message.match(/^[45]/)) {
let myErr = new Error(cmd.commandString + " -> " + message);
// Add Tor-specific information to the Error object.
- let idx = message.indexOf(' ');
+ let idx = message.indexOf(" ");
if (idx > 0) {
myErr.torStatusCode = message.substring(0, idx);
myErr.torMessage = message.substring(idx);
@@ -297,11 +313,15 @@ class ControlSocket {
}
cmd.reject(myErr);
} else {
- cmd.reject(new Error(`ControlSocket::_handleCommandReply received unexpected message:\n----\n${message}\n----`));
+ cmd.reject(
+ new Error(
+ `ControlSocket::_handleCommandReply received unexpected message:\n----\n${message}\n----`
+ )
+ );
}
// send next command if one is available
- if (this.commandQueue.length > 0) {
+ if (this.commandQueue.length) {
this._writeNextCommand();
}
}
@@ -322,7 +342,7 @@ class ControlSocket {
isOpen() {
return this._isOpen;
}
-};
+}
// ## io
// I/O utilities namespace
@@ -336,28 +356,33 @@ let io = {};
// Pass pushMessage to another function that needs a callback with a single string
// argument. Whenever dispatcher.pushMessage receives a string, the dispatcher will
// check for any regex matches and pass the string on to the corresponding callback(s).
-io.callbackDispatcher = function () {
+io.callbackDispatcher = function() {
let callbackPairs = [],
- removeCallback = function (aCallback) {
- callbackPairs = callbackPairs.filter(function ([regex, callback]) {
- return callback !== aCallback;
- });
- },
- addCallback = function (regex, callback) {
- if (callback) {
- callbackPairs.push([regex, callback]);
- }
- return function () { removeCallback(callback); };
- },
- pushMessage = function (message) {
- for (let [regex, callback] of callbackPairs) {
- if (message.match(regex)) {
- callback(message);
- }
- }
+ removeCallback = function(aCallback) {
+ callbackPairs = callbackPairs.filter(function([regex, callback]) {
+ return callback !== aCallback;
+ });
+ },
+ addCallback = function(regex, callback) {
+ if (callback) {
+ callbackPairs.push([regex, callback]);
+ }
+ return function() {
+ removeCallback(callback);
};
- return { pushMessage : pushMessage, removeCallback : removeCallback,
- addCallback : addCallback };
+ },
+ pushMessage = function(message) {
+ for (let [regex, callback] of callbackPairs) {
+ if (message.match(regex)) {
+ callback(message);
+ }
+ }
+ };
+ return {
+ pushMessage,
+ removeCallback,
+ addCallback,
+ };
};
// __io.controlSocket(ipcFile, host, port, password)__.
@@ -374,7 +399,7 @@ io.callbackDispatcher = function () {
// socket.removeNotificationCallback(callback);
// // Close the socket permanently
// socket.close();
-io.controlSocket = async function (ipcFile, host, port, password) {
+io.controlSocket = async function(ipcFile, host, port, password) {
let socket = new AsyncSocket(ipcFile, host, port);
let controlSocket = new ControlSocket(socket);
@@ -392,21 +417,23 @@ let utils = {};
// __utils.identity(x)__.
// Returns its argument unchanged.
-utils.identity = function (x) { return x; };
+utils.identity = function(x) {
+ return x;
+};
// __utils.isString(x)__.
// Returns true iff x is a string.
-utils.isString = function (x) {
- return typeof(x) === 'string' || x instanceof String;
+utils.isString = function(x) {
+ return typeof x === "string" || x instanceof String;
};
// __utils.capture(string, regex)__.
// Takes a string and returns an array of capture items, where regex must have a single
// capturing group and use the suffix /.../g to specify a global search.
-utils.capture = function (string, regex) {
+utils.capture = function(string, regex) {
let matches = [];
// Special trick to use string.replace for capturing multiple matches.
- string.replace(regex, function (a, captured) {
+ string.replace(regex, function(a, captured) {
matches.push(captured);
});
return matches;
@@ -415,15 +442,17 @@ utils.capture = function (string, regex) {
// __utils.extractor(regex)__.
// Returns a function that takes a string and returns an array of regex matches. The
// regex must use the suffix /.../g to specify a global search.
-utils.extractor = function (regex) {
- return function (text) {
+utils.extractor = function(regex) {
+ return function(text) {
return utils.capture(text, regex);
};
};
// __utils.splitLines(string)__.
// Splits a string into an array of strings, each corresponding to a line.
-utils.splitLines = function (string) { return string.split(/\r?\n/); };
+utils.splitLines = function(string) {
+ return string.split(/\r?\n/);
+};
// __utils.splitAtSpaces(string)__.
// Splits a string into chunks between spaces. Does not split at spaces
@@ -433,11 +462,14 @@ utils.splitAtSpaces = utils.extractor(/((\S*?"(.*?)")+\S*|\S+)/g);
// __utils.splitAtFirst(string, regex)__.
// Splits a string at the first instance of regex match. If no match is
// found, returns the whole string.
-utils.splitAtFirst = function (string, regex) {
+utils.splitAtFirst = function(string, regex) {
let match = string.match(regex);
- return match ? [ string.substring(0, match.index),
- string.substring(match.index + match[0].length) ]
- : string;
+ return match
+ ? [
+ string.substring(0, match.index),
+ string.substring(match.index + match[0].length),
+ ]
+ : string;
};
// __utils.splitAtEquals(string)__.
@@ -448,7 +480,7 @@ utils.splitAtEquals = utils.extractor(/(([^=]*?"(.*?)")+[^=]*|[^=]+)/g);
// __utils.mergeObjects(arrayOfObjects)__.
// Takes an array of objects like [{"a":"b"},{"c":"d"}] and merges to a single object.
// Pure function.
-utils.mergeObjects = function (arrayOfObjects) {
+utils.mergeObjects = function(arrayOfObjects) {
let result = {};
for (let obj of arrayOfObjects) {
for (let key in obj) {
@@ -468,10 +500,10 @@ utils.mergeObjects = function (arrayOfObjects) {
// ["streamID", "event", "circuitID", "IP"])
// // --> {"streamID" : "40", "event" : "FAILED", "circuitID" : "0",
// // "address" : "95.78.59.36:80", "REASON" : "CANT_ATTACH"}"
-utils.listMapData = function (parameterString, listNames) {
+utils.listMapData = function(parameterString, listNames) {
// Split out the space-delimited parameters.
let parameters = utils.splitAtSpaces(parameterString),
- dataMap = {};
+ dataMap = {};
// Assign listNames to the first n = listNames.length parameters.
for (let i = 0; i < listNames.length; ++i) {
dataMap[listNames[i]] = parameters[i];
@@ -506,13 +538,15 @@ let info = {};
// or single-line (with a `250-` or `250 ` prefix):
//
// 250-version=0.2.6.0-alpha-dev (git-b408125288ad6943)
-info.keyValueStringsFromMessage = utils.extractor(/^(250\+[\s\S]+?^\.|250[- ].+?)$/gmi);
+info.keyValueStringsFromMessage = utils.extractor(
+ /^(250\+[\s\S]+?^\.|250[- ].+?)$/gim
+);
// __info.applyPerLine(transformFunction)__.
// Returns a function that splits text into lines,
// and applies transformFunction to each line.
-info.applyPerLine = function (transformFunction) {
- return function (text) {
+info.applyPerLine = function(transformFunction) {
+ return function(text) {
return utils.splitLines(text.trim()).map(transformFunction);
};
};
@@ -521,23 +555,31 @@ info.applyPerLine = function (transformFunction) {
// Parses a router status entry as, described in
// https://gitweb.torproject.org/torspec.git/tree/dir-spec.txt
// (search for "router status entry")
-info.routerStatusParser = function (valueString) {
+info.routerStatusParser = function(valueString) {
let lines = utils.splitLines(valueString),
- objects = [];
+ objects = [];
for (let line of lines) {
// Drop first character and grab data following it.
let myData = line.substring(2),
- // Accumulate more maps with data, depending on the first character in the line.
- dataFun = {
- "r" : data => utils.listMapData(data, ["nickname", "identity", "digest",
- "publicationDate", "publicationTime",
- "IP", "ORPort", "DirPort"]),
- "a" : data => ({ "IPv6" : data }),
- "s" : data => ({ "statusFlags" : utils.splitAtSpaces(data) }),
- "v" : data => ({ "version" : data }),
- "w" : data => utils.listMapData(data, []),
- "p" : data => ({ "portList" : data.split(",") }),
- }[line.charAt(0)];
+ // Accumulate more maps with data, depending on the first character in the line.
+ dataFun = {
+ r: data =>
+ utils.listMapData(data, [
+ "nickname",
+ "identity",
+ "digest",
+ "publicationDate",
+ "publicationTime",
+ "IP",
+ "ORPort",
+ "DirPort",
+ ]),
+ a: data => ({ IPv6: data }),
+ s: data => ({ statusFlags: utils.splitAtSpaces(data) }),
+ v: data => ({ version: data }),
+ w: data => utils.listMapData(data, []),
+ p: data => ({ portList: data.split(",") }),
+ }[line.charAt(0)];
if (dataFun !== undefined) {
objects.push(dataFun(myData));
}
@@ -547,12 +589,12 @@ info.routerStatusParser = function (valueString) {
// __info.circuitStatusParser(line)__.
// Parse the output of a circuit status line.
-info.circuitStatusParser = function (line) {
- let data = utils.listMapData(line, ["id","status","circuit"]),
- circuit = data.circuit;
+info.circuitStatusParser = function(line) {
+ let data = utils.listMapData(line, ["id", "status", "circuit"]),
+ circuit = data.circuit;
// Parse out the individual circuit IDs and names.
if (circuit) {
- data.circuit = circuit.split(",").map(function (x) {
+ data.circuit = circuit.split(",").map(function(x) {
return x.split(/~|=/);
});
}
@@ -561,12 +603,15 @@ info.circuitStatusParser = function (line) {
// __info.streamStatusParser(line)__.
// Parse the output of a stream status line.
-info.streamStatusParser = function (text) {
- return utils.listMapData(text, ["StreamID", "StreamStatus",
- "CircuitID", "Target"]);
+info.streamStatusParser = function(text) {
+ return utils.listMapData(text, [
+ "StreamID",
+ "StreamStatus",
+ "CircuitID",
+ "Target",
+ ]);
};
-
// TODO: fix this parsing logic to handle bridgeLine correctly
// fingerprint/id is an optional parameter
// __info.bridgeParser(bridgeLine)__.
@@ -574,16 +619,26 @@ info.streamStatusParser = function (text) {
// a map containing the bridge's type, address, and ID.
info.bridgeParser = function(bridgeLine) {
let result = {},
- tokens = bridgeLine.split(/\s+/);
+ tokens = bridgeLine.split(/\s+/);
// First check if we have a "vanilla" bridge:
if (tokens[0].match(/^\d+\.\d+\.\d+\.\d+/)) {
result.type = "vanilla";
[result.address, result.ID] = tokens;
- // Several bridge types have a similar format:
+ // Several bridge types have a similar format:
} else {
result.type = tokens[0];
- if (["flashproxy", "fte", "meek", "meek_lite", "obfs3", "obfs4", "scramblesuit",
- "snowflake"].indexOf(result.type) >= 0) {
+ if (
+ [
+ "flashproxy",
+ "fte",
+ "meek",
+ "meek_lite",
+ "obfs3",
+ "obfs4",
+ "scramblesuit",
+ "snowflake",
+ ].includes(result.type)
+ ) {
[result.address, result.ID] = tokens.slice(1);
}
}
@@ -594,10 +649,10 @@ info.bridgeParser = function(bridgeLine) {
// A map of GETINFO and GETCONF keys to parsing function, which convert
// result strings to JavaScript data.
info.parsers = {
- "ns/id/" : info.routerStatusParser,
- "ip-to-country/" : utils.identity,
- "circuit-status" : info.applyPerLine(info.circuitStatusParser),
- "bridge" : info.bridgeParser,
+ "ns/id/": info.routerStatusParser,
+ "ip-to-country/": utils.identity,
+ "circuit-status": info.applyPerLine(info.circuitStatusParser),
+ bridge: info.bridgeParser,
// Currently unused parsers:
// "ns/name/" : info.routerStatusParser,
// "stream-status" : info.applyPerLine(info.streamStatusParser),
@@ -609,26 +664,31 @@ info.parsers = {
// Takes a key and determines the parser function that should be used to
// convert its corresponding valueString to JavaScript data.
info.getParser = function(key) {
- return info.parsers[key] ||
- info.parsers[key.substring(0, key.lastIndexOf("/") + 1)];
+ return (
+ info.parsers[key] ||
+ info.parsers[key.substring(0, key.lastIndexOf("/") + 1)]
+ );
};
// __info.stringToValue(string)__.
// Converts a key-value string as from GETINFO or GETCONF to a value.
-info.stringToValue = function (string) {
+info.stringToValue = function(string) {
// key should look something like `250+circuit-status=` or `250-circuit-status=...`
// or `250 circuit-status=...`
let matchForKey = string.match(/^250[ +-](.+?)=/),
- key = matchForKey ? matchForKey[1] : null;
- if (key === null) return null;
+ key = matchForKey ? matchForKey[1] : null;
+ if (key === null) {
+ return null;
+ }
// matchResult finds a single-line result for `250-` or `250 `,
// or a multi-line one for `250+`.
- let matchResult = string.match(/^250[ -].+?=(.*)$/) ||
- string.match(/^250\+.+?=([\s\S]*?)^\.$/m),
- // Retrieve the captured group (the text of the value in the key-value pair)
- valueString = matchResult ? matchResult[1] : null,
- // Get the parser function for the key found.
- parse = info.getParser(key.toLowerCase());
+ let matchResult =
+ string.match(/^250[ -].+?=(.*)$/) ||
+ string.match(/^250\+.+?=([\s\S]*?)^\.$/m),
+ // Retrieve the captured group (the text of the value in the key-value pair)
+ valueString = matchResult ? matchResult[1] : null,
+ // Get the parser function for the key found.
+ parse = info.getParser(key.toLowerCase());
if (parse === undefined) {
throw new Error("No parser found for '" + key + "'");
}
@@ -638,15 +698,16 @@ info.stringToValue = function (string) {
// __info.getMultipleResponseValues(message)__.
// Process multiple responses to a GETINFO or GETCONF request.
-info.getMultipleResponseValues = function (message) {
- return info.keyValueStringsFromMessage(message)
- .map(info.stringToValue)
- .filter(utils.identity);
+info.getMultipleResponseValues = function(message) {
+ return info
+ .keyValueStringsFromMessage(message)
+ .map(info.stringToValue)
+ .filter(utils.identity);
};
// __info.getInfo(controlSocket, key)__.
// Sends GETINFO for a single key. Returns a promise with the result.
-info.getInfo = function (aControlSocket, key) {
+info.getInfo = function(aControlSocket, key) {
if (!utils.isString(key)) {
return utils.rejectPromise("key argument should be a string");
}
@@ -657,7 +718,7 @@ info.getInfo = function (aControlSocket, key) {
// __info.getConf(aControlSocket, key)__.
// Sends GETCONF for a single key. Returns a promise with the result.
-info.getConf = function (aControlSocket, key) {
+info.getConf = function(aControlSocket, key) {
// GETCONF with a single argument returns results with
// one or more lines that look like `250[- ]key=value`.
// Any GETCONF lines that contain a single keyword only are currently dropped.
@@ -665,21 +726,23 @@ info.getConf = function (aControlSocket, key) {
if (!utils.isString(key)) {
return utils.rejectPromise("key argument should be a string");
}
- return aControlSocket.sendCommand("getconf " + key)
- .then(info.getMultipleResponseValues);
+ return aControlSocket
+ .sendCommand("getconf " + key)
+ .then(info.getMultipleResponseValues);
};
// ## onionAuth
// A namespace for functions related to tor's ONION_CLIENT_AUTH_* commands.
let onionAuth = {};
-onionAuth.keyInfoStringsFromMessage = utils.extractor(/^250-CLIENT\s+(.+)$/gmi);
+onionAuth.keyInfoStringsFromMessage = utils.extractor(/^250-CLIENT\s+(.+)$/gim);
onionAuth.keyInfoObjectsFromMessage = function(message) {
let keyInfoStrings = onionAuth.keyInfoStringsFromMessage(message);
- return keyInfoStrings.map(infoStr => utils.listMapData(infoStr,
- ["hsAddress", "typeAndKey"]));
-}
+ return keyInfoStrings.map(infoStr =>
+ utils.listMapData(infoStr, ["hsAddress", "typeAndKey"])
+ );
+};
// __onionAuth.viewKeys()__.
// Sends a ONION_CLIENT_AUTH_VIEW command to retrieve the list of private keys.
@@ -688,16 +751,22 @@ onionAuth.keyInfoObjectsFromMessage = function(message) {
// hsAddress
// typeAndKey
// Flags (e.g., "Permanent")
-onionAuth.viewKeys = function (aControlSocket) {
+onionAuth.viewKeys = function(aControlSocket) {
let cmd = "onion_client_auth_view";
- return aControlSocket.sendCommand(cmd).then(onionAuth.keyInfoObjectsFromMessage);
+ return aControlSocket
+ .sendCommand(cmd)
+ .then(onionAuth.keyInfoObjectsFromMessage);
};
// __onionAuth.add(controlSocket, hsAddress, b64PrivateKey, isPermanent)__.
// Sends a ONION_CLIENT_AUTH_ADD command to add a private key to the
// Tor configuration.
-onionAuth.add = function (aControlSocket, hsAddress, b64PrivateKey,
- isPermanent) {
+onionAuth.add = function(
+ aControlSocket,
+ hsAddress,
+ b64PrivateKey,
+ isPermanent
+) {
if (!utils.isString(hsAddress)) {
return utils.rejectPromise("hsAddress argument should be a string");
}
@@ -708,15 +777,16 @@ onionAuth.add = function (aControlSocket, hsAddress, b64PrivateKey,
const keyType = "x25519";
let cmd = `onion_client_auth_add ${hsAddress} ${keyType}:${b64PrivateKey}`;
- if (isPermanent)
+ if (isPermanent) {
cmd += " Flags=Permanent";
+ }
return aControlSocket.sendCommand(cmd);
};
// __onionAuth.remove(controlSocket, hsAddress)__.
// Sends a ONION_CLIENT_AUTH_REMOVE command to remove a private key from the
// Tor configuration.
-onionAuth.remove = function (aControlSocket, hsAddress) {
+onionAuth.remove = function(aControlSocket, hsAddress) {
if (!utils.isString(hsAddress)) {
return utils.rejectPromise("hsAddress argument should be a string");
}
@@ -725,7 +795,6 @@ onionAuth.remove = function (aControlSocket, hsAddress) {
return aControlSocket.sendCommand(cmd);
};
-
// ## event
// Handlers for events
@@ -735,7 +804,7 @@ let event = {};
// A map of EVENT keys to parsing functions, which convert result strings to JavaScript
// data.
event.parsers = {
- "stream" : info.streamStatusParser,
+ stream: info.streamStatusParser,
// Currently unused:
// "circ" : info.circuitStatusParser,
};
@@ -743,9 +812,11 @@ event.parsers = {
// __event.messageToData(type, message)__.
// Extract the data from an event. Note, at present
// we only extract streams that look like `"650" SP...`
-event.messageToData = function (type, message) {
+event.messageToData = function(type, message) {
let dataText = message.match(/^650 \S+?\s(.*)/m)[1];
- return (dataText && type.toLowerCase() in event.parsers) ? event.parsers[type.toLowerCase()](dataText) : null;
+ return dataText && type.toLowerCase() in event.parsers
+ ? event.parsers[type.toLowerCase()](dataText)
+ : null;
};
// __event.watchEvent(controlSocket, type, filter, onData)__.
@@ -753,17 +824,20 @@ event.messageToData = function (type, message) {
// data is passed to the onData callback. Returns a zero arg function that
// stops watching the event. Note: we only observe `"650" SP...` events
// currently (no `650+...` or `650-...` events).
-event.watchEvent = function (controlSocket, type, filter, onData, raw=false) {
- return controlSocket.addNotificationCallback(new RegExp("^650 " + type),
- function (message) {
+event.watchEvent = function(controlSocket, type, filter, onData, raw = false) {
+ return controlSocket.addNotificationCallback(
+ new RegExp("^650 " + type),
+ function(message) {
let data = event.messageToData(type, message);
if (filter === null || filter(data)) {
if (raw || !data) {
- return onData(message);
+ onData(message);
+ return;
}
onData(data);
}
- });
+ }
+ );
};
// ## tor
@@ -778,22 +852,23 @@ tor.controllerCache = new Map();
// __tor.controller(ipcFile, host, port, password)__.
// Creates a tor controller at the given ipcFile or host and port, with the
// given password.
-tor.controller = async function (ipcFile, host, port, password) {
+tor.controller = async function(ipcFile, host, port, password) {
let socket = await io.controlSocket(ipcFile, host, port, password);
- return { getInfo : key => info.getInfo(socket, key),
- getConf : key => info.getConf(socket, key),
- onionAuthViewKeys : () => onionAuth.viewKeys(socket),
- onionAuthAdd : (hsAddress, b64PrivateKey, isPermanent) =>
- onionAuth.add(socket, hsAddress, b64PrivateKey,
- isPermanent),
- onionAuthRemove : (hsAddress) =>
- onionAuth.remove(socket, hsAddress),
- watchEvent : (type, filter, onData, raw=false) =>
- event.watchEvent(socket, type, filter, onData, raw),
- isOpen : () => socket.isOpen(),
- close : () => { socket.close(); },
- sendCommand: cmd => socket.sendCommand(cmd),
- };
+ return {
+ getInfo: key => info.getInfo(socket, key),
+ getConf: key => info.getConf(socket, key),
+ onionAuthViewKeys: () => onionAuth.viewKeys(socket),
+ onionAuthAdd: (hsAddress, b64PrivateKey, isPermanent) =>
+ onionAuth.add(socket, hsAddress, b64PrivateKey, isPermanent),
+ onionAuthRemove: hsAddress => onionAuth.remove(socket, hsAddress),
+ watchEvent: (type, filter, onData, raw = false) =>
+ event.watchEvent(socket, type, filter, onData, raw),
+ isOpen: () => socket.isOpen(),
+ close: () => {
+ socket.close();
+ },
+ sendCommand: cmd => socket.sendCommand(cmd),
+ };
};
// ## Export
@@ -804,7 +879,7 @@ let controlPortInfo = {};
// Sets Tor control port connection parameters to be used in future calls to
// the controller() function. Example:
// configureControlPortModule(undefined, "127.0.0.1", 9151, "MyPassw0rd");
-var configureControlPortModule = function (ipcFile, host, port, password) {
+var configureControlPortModule = function(ipcFile, host, port, password) {
controlPortInfo.ipcFile = ipcFile;
controlPortInfo.host = host;
controlPortInfo.port = port || 9151;
@@ -827,28 +902,28 @@ var configureControlPortModule = function (ipcFile, host, port, password) {
// let replyPromise = c.getInfo("ip-to-country/16.16.16.16");
// // Close the controller permanently
// c.close();
-var controller = async function (avoidCache) {
-
- if (!controlPortInfo.ipcFile && !controlPortInfo.host)
+var controller = async function(avoidCache) {
+ if (!controlPortInfo.ipcFile && !controlPortInfo.host) {
throw new Error("Please call configureControlPortModule first");
+ }
- const dest = (controlPortInfo.ipcFile)
- ? `unix:${controlPortInfo.ipcFile.path}`
- : `${controlPortInfo.host}:${controlPortInfo.port}`;
+ const dest = controlPortInfo.ipcFile
+ ? `unix:${controlPortInfo.ipcFile.path}`
+ : `${controlPortInfo.host}:${controlPortInfo.port}`;
// constructor shorthand
- const newTorController =
- async () => {
- return await tor.controller(
- controlPortInfo.ipcFile,
- controlPortInfo.host,
- controlPortInfo.port,
- controlPortInfo.password);
- };
+ const newTorController = async () => {
+ return tor.controller(
+ controlPortInfo.ipcFile,
+ controlPortInfo.host,
+ controlPortInfo.port,
+ controlPortInfo.password
+ );
+ };
// avoid cache so always return a new controller
if (avoidCache) {
- return await newTorController();
+ return newTorController();
}
// first check our cache and see if we already have one
@@ -872,17 +947,19 @@ var controller = async function (avoidCache) {
// Same as controller() function, but explicitly waits until there is a tor daemon
// to connect to (either launched by tor-launcher, or if we have an existing system
// tor daemon)
-var wait_for_controller = async function(avoidCache) {
+var wait_for_controller = function(avoidCache) {
// if tor process is running (either ours or system) immediately return controller
- if (!TorProtocolService.ownsTorDaemon ||
- TorProtocolService.torProcessStatus == TorProcessStatus.Running) {
- return await controller(avoidCache);
+ if (
+ !TorProtocolService.ownsTorDaemon ||
+ TorProtocolService.torProcessStatus == TorProcessStatus.Running
+ ) {
+ return controller(avoidCache);
}
// otherwise we must wait for tor to finish launching before resolving
return new Promise((resolve, reject) => {
let observer = {
- observe : async (subject, topic, data) => {
+ observe: async (subject, topic, data) => {
if (topic === TorTopics.ProcessIsReady) {
try {
resolve(await controller(avoidCache));
@@ -898,4 +975,8 @@ var wait_for_controller = async function(avoidCache) {
};
// Export functions for external use.
-var EXPORTED_SYMBOLS = ["configureControlPortModule", "controller", "wait_for_controller"];
+var EXPORTED_SYMBOLS = [
+ "configureControlPortModule",
+ "controller",
+ "wait_for_controller",
+];
diff --git a/modules/utils.js b/modules/utils.js
index b726342b..7ccd2da1 100644
--- a/modules/utils.js
+++ b/modules/utils.js
@@ -11,12 +11,16 @@ let prefs = Services.prefs;
// __getPrefValue(prefName)__
// Returns the current value of a preference, regardless of its type.
-var getPrefValue = function (prefName) {
- switch(prefs.getPrefType(prefName)) {
- case prefs.PREF_BOOL: return prefs.getBoolPref(prefName);
- case prefs.PREF_INT: return prefs.getIntPref(prefName);
- case prefs.PREF_STRING: return prefs.getCharPref(prefName);
- default: return null;
+var getPrefValue = function(prefName) {
+ switch (prefs.getPrefType(prefName)) {
+ case prefs.PREF_BOOL:
+ return prefs.getBoolPref(prefName);
+ case prefs.PREF_INT:
+ return prefs.getIntPref(prefName);
+ case prefs.PREF_STRING:
+ return prefs.getCharPref(prefName);
+ default:
+ return null;
}
};
@@ -24,18 +28,24 @@ var getPrefValue = function (prefName) {
// Applies prefHandler whenever the value of the pref changes.
// If init is true, applies prefHandler to the current value.
// Returns a zero-arg function that unbinds the pref.
-var bindPref = function (prefName, prefHandler, init = false) {
- let update = () => { prefHandler(getPrefValue(prefName)); },
- observer = { observe : function (subject, topic, data) {
- if (data === prefName) {
- update();
- }
- } };
- prefs.addObserver(prefName, observer, false);
+var bindPref = function(prefName, prefHandler, init = false) {
+ let update = () => {
+ prefHandler(getPrefValue(prefName));
+ },
+ observer = {
+ observe(subject, topic, data) {
+ if (data === prefName) {
+ update();
+ }
+ },
+ };
+ prefs.addObserver(prefName, observer);
if (init) {
update();
}
- return () => { prefs.removeObserver(prefName, observer); };
+ return () => {
+ prefs.removeObserver(prefName, observer);
+ };
};
// __bindPrefAndInit(prefName, prefHandler)__
@@ -43,7 +53,7 @@ var bindPref = function (prefName, prefHandler, init = false) {
// Re-applies prefHandler whenever the value of the pref changes.
// Returns a zero-arg function that unbinds the pref.
var bindPrefAndInit = (prefName, prefHandler) =>
- bindPref(prefName, prefHandler, true);
+ bindPref(prefName, prefHandler, true);
// ## Observers
@@ -51,15 +61,15 @@ var bindPrefAndInit = (prefName, prefHandler) =>
// Observe the given topic. When notification of that topic
// occurs, calls callback(subject, data). Returns a zero-arg
// function that stops observing.
-var observe = function (topic, callback) {
+var observe = function(topic, callback) {
let observer = {
- observe: function (aSubject, aTopic, aData) {
+ observe(aSubject, aTopic, aData) {
if (topic === aTopic) {
callback(aSubject, aData);
}
},
};
- Services.obs.addObserver(observer, topic, false);
+ Services.obs.addObserver(observer, topic);
return () => Services.obs.removeObserver(observer, topic);
};
@@ -67,12 +77,13 @@ var observe = function (topic, callback) {
// __env__.
// Provides access to process environment variables.
-let env = Cc["@mozilla.org/process/environment;1"]
- .getService(Ci.nsIEnvironment);
+let env = Cc["@mozilla.org/process/environment;1"].getService(
+ Ci.nsIEnvironment
+);
// __getEnv(name)__.
// Reads the environment variable of the given name.
-var getEnv = function (name) {
+var getEnv = function(name) {
return env.exists(name) ? env.get(name) : undefined;
};
@@ -91,17 +102,15 @@ let dialogsByName = {};
// __showDialog(parent, url, name, features, arg1, arg2, ...)__.
// Like window.openDialog, but if the window is already
// open, just focuses it instead of opening a new one.
-var showDialog = function (parent, url, name, features) {
+var showDialog = function(parent, url, name, features) {
let existingDialog = dialogsByName[name];
if (existingDialog && !existingDialog.closed) {
existingDialog.focus();
return existingDialog;
- } else {
- let newDialog = parent.openDialog.apply(parent,
- Array.slice(arguments, 1));
- dialogsByName[name] = newDialog;
- return newDialog;
}
+ let newDialog = parent.openDialog.apply(parent, Array.slice(arguments, 1));
+ dialogsByName[name] = newDialog;
+ return newDialog;
};
// ## Tor control protocol utility functions
@@ -112,71 +121,69 @@ let _torControl = {
// Returns the unescaped string. Throws upon failure.
// Within Tor Launcher, the file components/tl-protocol.js also contains a
// copy of _strUnescape().
- _strUnescape: function(aStr)
- {
- if (!aStr)
+ _strUnescape(aStr) {
+ if (!aStr) {
return aStr;
+ }
var len = aStr.length;
- if ((len < 2) || ('"' != aStr.charAt(0)) || ('"' != aStr.charAt(len - 1)))
+ if (len < 2 || '"' != aStr.charAt(0) || '"' != aStr.charAt(len - 1)) {
return aStr;
+ }
const kHexRE = /[0-9A-Fa-f]{2}/;
const kOctalRE = /[0-7]{3}/;
var rv = "";
var i = 1;
var lastCharIndex = len - 2;
- while (i <= lastCharIndex)
- {
+ while (i <= lastCharIndex) {
var c = aStr.charAt(i);
- if ('\\' == c)
- {
- if (++i > lastCharIndex)
+ if ("\\" == c) {
+ if (++i > lastCharIndex) {
throw new Error("missing character after \\");
+ }
c = aStr.charAt(i);
- if ('n' == c)
- rv += '\n';
- else if ('r' == c)
- rv += '\r';
- else if ('t' == c)
- rv += '\t';
- else if ('x' == c)
- {
- if ((i + 2) > lastCharIndex)
+ if ("n" == c) {
+ rv += "\n";
+ } else if ("r" == c) {
+ rv += "\r";
+ } else if ("t" == c) {
+ rv += "\t";
+ } else if ("x" == c) {
+ if (i + 2 > lastCharIndex) {
throw new Error("not enough hex characters");
+ }
let s = aStr.substr(i + 1, 2);
- if (!kHexRE.test(s))
+ if (!kHexRE.test(s)) {
throw new Error("invalid hex characters");
+ }
let val = parseInt(s, 16);
rv += String.fromCharCode(val);
i += 3;
- }
- else if (this._isDigit(c))
- {
+ } else if (this._isDigit(c)) {
let s = aStr.substr(i, 3);
- if ((i + 2) > lastCharIndex)
+ if (i + 2 > lastCharIndex) {
throw new Error("not enough octal characters");
+ }
- if (!kOctalRE.test(s))
+ if (!kOctalRE.test(s)) {
throw new Error("invalid octal characters");
+ }
let val = parseInt(s, 8);
rv += String.fromCharCode(val);
i += 3;
- }
- else // "\\" and others
- {
+ } // "\\" and others
+ else {
rv += c;
++i;
}
- }
- else if ('"' == c)
- throw new Error("unescaped \" within string");
- else
- {
+ } else if ('"' == c) {
+ throw new Error('unescaped " within string');
+ } else {
rv += c;
++i;
}
@@ -188,8 +195,7 @@ let _torControl = {
// Within Tor Launcher, the file components/tl-protocol.js also contains a
// copy of _isDigit().
- _isDigit: function(aChar)
- {
+ _isDigit(aChar) {
const kRE = /^\d$/;
return aChar && kRE.test(aChar);
},
@@ -206,30 +212,35 @@ var unescapeTorString = function(str) {
var show_torbrowser_manual = () => {
let availableLocales = ["de", "en", "es", "fr", "nl", "pt", "tr", "vi", "zh"];
let shortLocale = getLocale().substring(0, 2);
- return availableLocales.indexOf(shortLocale) >= 0;
-}
+ return availableLocales.includes(shortLocale);
+};
-var getFPDFromHost = (hostname) => {
+var getFPDFromHost = hostname => {
try {
return Services.eTLD.getBaseDomainFromHost(hostname);
} catch (e) {
- if (e.result == Cr.NS_ERROR_HOST_IS_IP_ADDRESS ||
- e.result == Cr.NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
+ if (
+ e.result == Cr.NS_ERROR_HOST_IS_IP_ADDRESS ||
+ e.result == Cr.NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS
+ ) {
return hostname;
}
}
return null;
-}
+};
// Assuming this is called with gBrowser.selectedBrowser
-var getDomainForBrowser = (browser) => {
+var getDomainForBrowser = browser => {
let fpd = browser.contentPrincipal.originAttributes.firstPartyDomain;
// Bug 31562: For neterror or certerror, get the original URL from
// browser.currentURI and use it to calculate the firstPartyDomain.
let knownErrors = ["about:neterror", "about:certerror"];
let documentURI = browser.documentURI;
- if (documentURI && documentURI.schemeIs('about') &&
- knownErrors.some(x => documentURI.spec.startsWith(x))) {
+ if (
+ documentURI &&
+ documentURI.schemeIs("about") &&
+ knownErrors.some(x => documentURI.spec.startsWith(x))
+ ) {
let knownSchemes = ["http", "https", "ftp"];
let currentURI = browser.currentURI;
if (currentURI && knownSchemes.some(x => currentURI.schemeIs(x))) {
@@ -239,58 +250,71 @@ var getDomainForBrowser = (browser) => {
return fpd;
};
-var m_tb_torlog = Cc["@torproject.org/torbutton-logger;1"]
-.getService(Ci.nsISupports).wrappedJSObject;
+var m_tb_torlog = Cc["@torproject.org/torbutton-logger;1"].getService(
+ Ci.nsISupports
+).wrappedJSObject;
var m_tb_string_bundle = torbutton_get_stringbundle();
function torbutton_safelog(nLevel, sMsg, scrub) {
- m_tb_torlog.safe_log(nLevel, sMsg, scrub);
- return true;
+ m_tb_torlog.safe_log(nLevel, sMsg, scrub);
+ return true;
}
function torbutton_log(nLevel, sMsg) {
- m_tb_torlog.log(nLevel, sMsg);
+ m_tb_torlog.log(nLevel, sMsg);
- // So we can use it in boolean expressions to determine where the
- // short-circuit is..
- return true;
+ // So we can use it in boolean expressions to determine where the
+ // short-circuit is..
+ return true;
}
// load localization strings
-function torbutton_get_stringbundle()
-{
- var o_stringbundle = false;
-
- try {
- var oBundle = Services.strings;
- o_stringbundle = oBundle.createBundle("chrome://torbutton/locale/torbutton.properties");
- } catch(err) {
- o_stringbundle = false;
- }
- if (!o_stringbundle) {
- torbutton_log(5, 'ERROR (init): failed to find torbutton-bundle');
- }
+function torbutton_get_stringbundle() {
+ var o_stringbundle = false;
- return o_stringbundle;
-}
+ try {
+ var oBundle = Services.strings;
+ o_stringbundle = oBundle.createBundle(
+ "chrome://torbutton/locale/torbutton.properties"
+ );
+ } catch (err) {
+ o_stringbundle = false;
+ }
+ if (!o_stringbundle) {
+ torbutton_log(5, "ERROR (init): failed to find torbutton-bundle");
+ }
-function torbutton_get_property_string(propertyname)
-{
- try {
- if (!m_tb_string_bundle) {
- m_tb_string_bundle = torbutton_get_stringbundle();
- }
+ return o_stringbundle;
+}
- return m_tb_string_bundle.GetStringFromName(propertyname);
- } catch(e) {
- torbutton_log(4, "Unlocalized string "+propertyname);
+function torbutton_get_property_string(propertyname) {
+ try {
+ if (!m_tb_string_bundle) {
+ m_tb_string_bundle = torbutton_get_stringbundle();
}
- return propertyname;
+ return m_tb_string_bundle.GetStringFromName(propertyname);
+ } catch (e) {
+ torbutton_log(4, "Unlocalized string " + propertyname);
+ }
+
+ return propertyname;
}
// Export utility functions for external use.
-let EXPORTED_SYMBOLS = ["bindPref", "bindPrefAndInit", "getEnv", "getLocale", "getDomainForBrowser",
- "getPrefValue", "observe", "showDialog", "show_torbrowser_manual", "unescapeTorString",
- "torbutton_safelog", "torbutton_log", "torbutton_get_property_string"];
+let EXPORTED_SYMBOLS = [
+ "bindPref",
+ "bindPrefAndInit",
+ "getEnv",
+ "getLocale",
+ "getDomainForBrowser",
+ "getPrefValue",
+ "observe",
+ "showDialog",
+ "show_torbrowser_manual",
+ "unescapeTorString",
+ "torbutton_safelog",
+ "torbutton_log",
+ "torbutton_get_property_string",
+];
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the tbb-commits
mailing list