commit 095cf9496fbf4ae12d499bb21d00d1dc84af0147 Author: Alex Catarineu acat@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"];
tor-commits@lists.torproject.org