commit 095cf9496fbf4ae12d499bb21d00d1dc84af0147
Author: Alex Catarineu <acat(a)torproject.org>
Date: Thu Apr 25 20:56:58 2019 +0200
Bug 30115: map browser + domain -> credentials to fix UI issues.
Should also fix #27749 and #25145.
---
src/chrome/content/tor-circuit-display.js | 29 +++++++++++++++---------
src/chrome/content/torbutton.js | 37 +++++++------------------------
src/modules/utils.js | 35 +++++++++++++++++++++++++++--
3 files changed, 59 insertions(+), 42 deletions(-)
diff --git a/src/chrome/content/tor-circuit-display.js b/src/chrome/content/tor-circuit-display.js
index 5fc92e48..5ecbe7d7 100644
--- a/src/chrome/content/tor-circuit-display.js
+++ b/src/chrome/content/tor-circuit-display.js
@@ -33,7 +33,7 @@ Cu.import("resource://gre/modules/Services.jsm");
let { controller } = Cu.import("resource://torbutton/modules/tor-control-port.js", {});
// Utility functions
-let { bindPrefAndInit, observe, getLocale } = Cu.import("resource://torbutton/modules/utils.js", {});
+let { bindPrefAndInit, observe, getLocale, getDomainForBrowser } = Cu.import("resource://torbutton/modules/utils.js", {});
// Make the TorButton logger available.
let logger = Cc["@torproject.org/torbutton-logger;1"]
@@ -43,12 +43,12 @@ let logger = Cc["@torproject.org/torbutton-logger;1"]
// A mutable map that stores the current nodes for each
// SOCKS username/password pair.
-let credentialsToNodeDataMap = {},
+let credentialsToNodeDataMap = new Map(),
// A mutable map that reports `true` for IDs of "mature" circuits
// (those that have conveyed a stream).
- knownCircuitIDs = {},
+ knownCircuitIDs = new Map(),
// A mutable map that records the SOCKS credentials for the
- // latest channels for each browser.
+ // latest channels for each browser + domain.
browserToCredentialsMap = new Map();
// __trimQuotes(s)__.
@@ -139,9 +139,9 @@ let collectIsolationData = function (aController, updateUI) {
"STREAM",
streamEvent => streamEvent.StreamStatus === "SENTCONNECT",
async (streamEvent) => {
- if (!knownCircuitIDs[streamEvent.CircuitID]) {
+ if (!knownCircuitIDs.get(streamEvent.CircuitID)) {
logger.eclog(3, "streamEvent.CircuitID: " + streamEvent.CircuitID);
- knownCircuitIDs[streamEvent.CircuitID] = true;
+ knownCircuitIDs.set(streamEvent.CircuitID, true);
let circuitStatus = await getCircuitStatusByID(aController, streamEvent.CircuitID),
credentials = circuitStatus ?
(trimQuotes(circuitStatus.SOCKS_USERNAME) + "|" +
@@ -149,7 +149,7 @@ let collectIsolationData = function (aController, updateUI) {
null;
if (credentials) {
let nodeData = await nodeDataForCircuit(aController, circuitStatus);
- credentialsToNodeDataMap[credentials] = nodeData;
+ credentialsToNodeDataMap.set(credentials, nodeData);
updateUI();
}
}
@@ -183,8 +183,12 @@ let collectBrowserCredentials = function () {
let proxyInfo = chan.QueryInterface(Ci.nsIProxiedChannel).proxyInfo;
let browser = browserForChannel(chan);
if (browser && proxyInfo) {
- browserToCredentialsMap.set(browser, [proxyInfo.username,
- proxyInfo.password]);
+ if (!browserToCredentialsMap.has(browser)) {
+ browserToCredentialsMap.set(browser, new Map());
+ }
+ 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}`);
@@ -264,10 +268,13 @@ let appendHtml = (parent, data) => parent.appendChild(htmlTree(data));
// Obtains the circuit used by the given browser.
let currentCircuitData = function (browser) {
if (browser) {
- let credentials = browserToCredentialsMap.get(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[`${SOCKS_username}|${SOCKS_password}`];
+ let nodeData = credentialsToNodeDataMap.get(`${SOCKS_username}|${SOCKS_password}`);
let domain = SOCKS_username;
return { domain, nodeData };
}
diff --git a/src/chrome/content/torbutton.js b/src/chrome/content/torbutton.js
index 6ea51190..50f758c4 100644
--- a/src/chrome/content/torbutton.js
+++ b/src/chrome/content/torbutton.js
@@ -9,16 +9,19 @@
let { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
-let { showDialog, show_torbrowser_manual } = Cu.import("resource://torbutton/modules/utils.js", {});
-let { unescapeTorString } = Cu.import("resource://torbutton/modules/utils.js", {});
+let {
+ showDialog,
+ show_torbrowser_manual,
+ unescapeTorString,
+ bindPrefAndInit,
+ getDomainForBrowser,
+} = Cu.import("resource://torbutton/modules/utils.js", {});
let SecurityPrefs = Cu.import("resource://torbutton/modules/security-prefs.js", {});
-let { bindPrefAndInit } = Cu.import("resource://torbutton/modules/utils.js", {});
const k_tb_last_browser_version_pref = "extensions.torbutton.lastBrowserVersion";
const k_tb_browser_update_needed_pref = "extensions.torbutton.updateNeeded";
const k_tb_last_update_check_pref = "extensions.torbutton.lastUpdateCheck";
const k_tb_tor_check_failed_topic = "Torbutton:TorCheckFailed";
-const k_tb_about_uri_first_party_domain = "about.ef2a7dd5-93bc-417f-a698-142c3116864f.mozilla";
var m_tb_prefs = Services.prefs;
@@ -860,31 +863,7 @@ function torbutton_send_ctrl_cmd(command) {
// Bug 1506 P4: Needed for New IP Address
function torbutton_new_circuit() {
- let firstPartyDomain = gBrowser.contentPrincipal.originAttributes
- .firstPartyDomain;
- // Bug 22538: For neterror or certerror, get firstPartyDomain causing it from the u param
- if (firstPartyDomain === k_tb_about_uri_first_party_domain) {
- let knownErrors = ["about:neterror", "about:certerror"];
- let origin = gBrowser.contentPrincipal.origin || '';
- if (knownErrors.some(x => origin.startsWith(x))) {
- try {
- let urlOrigin = new URL(origin);
- let { hostname } = new URL(urlOrigin.searchParams.get('u'));
- if (hostname) {
- try {
- firstPartyDomain = Services.eTLD.getBaseDomainFromHost(hostname);
- } catch (e) {
- if (e.result == Cr.NS_ERROR_HOST_IS_IP_ADDRESS ||
- e.result == Cr.NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
- firstPartyDomain = hostname;
- }
- }
- }
- } catch (e) {
- torbutton_log(4, "Exception on new circuit" +e);
- }
- }
- }
+ let firstPartyDomain = getDomainForBrowser(gBrowser);
let domainIsolator = Cc["@torproject.org/domain-isolator;1"]
.getService(Ci.nsISupports).wrappedJSObject;
diff --git a/src/modules/utils.js b/src/modules/utils.js
index 5af071ec..d7baca6e 100644
--- a/src/modules/utils.js
+++ b/src/modules/utils.js
@@ -2,11 +2,17 @@
// Various helpful utility functions.
// ### Shortcut
-const Cu = Components.utils;
+const { Cu: utils, Cr: results } = Components;
// ### Import Mozilla Services
Cu.import("resource://gre/modules/Services.jsm");
+// ### Import global URL
+Cu.importGlobalProperties(["URL"]);
+
+// ### About firstPartyDomain literal
+const k_tb_about_uri_first_party_domain = "about.ef2a7dd5-93bc-417f-a698-142c3116864f.mozilla";
+
// ## Pref utils
// __prefs__. A shortcut to Mozilla Services.prefs.
@@ -212,7 +218,32 @@ var show_torbrowser_manual = () => {
return availableLocales.indexOf(shortLocale) >= 0;
}
+var getDomainForBrowser = (browser) => {
+ let firstPartyDomain = browser.contentPrincipal.originAttributes.firstPartyDomain;
+ // Bug 22538: For neterror or certerror, get firstPartyDomain causing it from the u param
+ if (firstPartyDomain === k_tb_about_uri_first_party_domain) {
+ let knownErrors = ["about:neterror", "about:certerror"];
+ let origin = browser.contentPrincipal.origin || '';
+ if (knownErrors.some(x => origin.startsWith(x))) {
+ try {
+ let urlOrigin = new URL(origin);
+ let { hostname } = new URL(urlOrigin.searchParams.get('u'));
+ if (hostname) {
+ try {
+ firstPartyDomain = Services.eTLD.getBaseDomainFromHost(hostname);
+ } catch (e) {
+ if (e.result == Cr.NS_ERROR_HOST_IS_IP_ADDRESS ||
+ e.result == Cr.NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
+ firstPartyDomain = hostname;
+ }
+ }
+ }
+ } catch (e) {}
+ }
+ }
+ return firstPartyDomain;
+};
// Export utility functions for external use.
-let EXPORTED_SYMBOLS = ["bindPref", "bindPrefAndInit", "getEnv", "getLocale",
+let EXPORTED_SYMBOLS = ["bindPref", "bindPrefAndInit", "getEnv", "getLocale", "getDomainForBrowser",
"getPrefValue", "observe", "showDialog", "show_torbrowser_manual", "unescapeTorString"];