lists.torproject.org
Sign In Sign Up
Manage this list Sign In Sign Up

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

tbb-commits

Thread Start a new thread
Threads by month
  • ----- 2026 -----
  • May
  • April
  • March
  • February
  • January
  • ----- 2025 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2022 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2021 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2020 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2019 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2018 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2017 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2016 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2015 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2014 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
tbb-commits@lists.torproject.org

  • 1 participants
  • 20447 discussions
[tor-browser/tor-browser-87.0b4-10.5-1] Bug 32418: Allow updates to be disabled via an enterprise policy.
by sysrqb@torproject.org 11 Mar '21

11 Mar '21
commit 503706ce9002e4bfa35a22769a681d89651c5eba Author: Kathy Brade <brade(a)pearlcrescent.com> Date: Thu Apr 16 17:07:09 2020 -0400 Bug 32418: Allow updates to be disabled via an enterprise policy. Restrict the Enterprise Policies mechanism to only consult a policies.json file (avoiding the Windows Registry and macOS's file system attributes). Add a few disabledByPolicy() checks to the update service to avoid extraneous (and potentially confusing) log messages when updates are disabled by policy. Sample content for distribution/policies.json: { "policies": { "DisableAppUpdate": true } } On Linux, avoid reading policies from /etc/firefox/policies/policies.json --- .../enterprisepolicies/EnterprisePoliciesParent.jsm | 14 ++++++++++++-- toolkit/components/enterprisepolicies/moz.build | 3 +++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/toolkit/components/enterprisepolicies/EnterprisePoliciesParent.jsm b/toolkit/components/enterprisepolicies/EnterprisePoliciesParent.jsm index 775144e8a649..9fe916236cbc 100644 --- a/toolkit/components/enterprisepolicies/EnterprisePoliciesParent.jsm +++ b/toolkit/components/enterprisepolicies/EnterprisePoliciesParent.jsm @@ -4,6 +4,10 @@ var EXPORTED_SYMBOLS = ["EnterprisePoliciesManager"]; +// To ensure that policies intended for Firefox or another browser will not +// be used, Tor Browser only looks for policies in ${InstallDir}/distribution +#define AVOID_SYSTEM_POLICIES MOZ_PROXY_BYPASS_PROTECTION + const { XPCOMUtils } = ChromeUtils.import( "resource://gre/modules/XPCOMUtils.jsm" ); @@ -13,9 +17,11 @@ const { AppConstants } = ChromeUtils.import( ); XPCOMUtils.defineLazyModuleGetters(this, { +#ifndef AVOID_SYSTEM_POLICIES WindowsGPOParser: "resource://gre/modules/policies/WindowsGPOParser.jsm", macOSPoliciesParser: "resource://gre/modules/policies/macOSPoliciesParser.jsm", +#endif Policies: "resource:///modules/policies/Policies.jsm", JsonSchemaValidator: "resource://gre/modules/components-utils/JsonSchemaValidator.jsm", @@ -140,11 +146,13 @@ EnterprisePoliciesManager.prototype = { _chooseProvider() { let platformProvider = null; +#ifndef AVOID_SYSTEM_POLICIES if (AppConstants.platform == "win") { platformProvider = new WindowsGPOPoliciesProvider(); } else if (AppConstants.platform == "macosx") { platformProvider = new macOSPoliciesProvider(); } +#endif let jsonProvider = new JSONPoliciesProvider(); if (platformProvider && platformProvider.hasPolicies) { if (jsonProvider.hasPolicies) { @@ -491,7 +499,7 @@ class JSONPoliciesProvider { _getConfigurationFile() { let configFile = null; - +#ifndef AVOID_SYSTEM_POLICIES if (AppConstants.platform == "linux") { let systemConfigFile = Cc["@mozilla.org/file/local;1"].createInstance( Ci.nsIFile @@ -504,7 +512,7 @@ class JSONPoliciesProvider { return systemConfigFile; } } - +#endif try { let perUserPath = Services.prefs.getBoolPref(PREF_PER_USER_DIR, false); if (perUserPath) { @@ -585,6 +593,7 @@ class JSONPoliciesProvider { } } +#ifndef AVOID_SYSTEM_POLICIES class WindowsGPOPoliciesProvider { constructor() { this._policies = null; @@ -686,3 +695,4 @@ class CombinedProvider { return false; } } +#endif diff --git a/toolkit/components/enterprisepolicies/moz.build b/toolkit/components/enterprisepolicies/moz.build index 09d2046e1bd7..3f685d3fbbd6 100644 --- a/toolkit/components/enterprisepolicies/moz.build +++ b/toolkit/components/enterprisepolicies/moz.build @@ -19,6 +19,9 @@ if CONFIG["MOZ_WIDGET_TOOLKIT"] != "android": EXTRA_JS_MODULES += [ "EnterprisePolicies.jsm", "EnterprisePoliciesContent.jsm", + ] + + EXTRA_PP_JS_MODULES += [ "EnterprisePoliciesParent.jsm", ]
1 0
0 0
[tor-browser/tor-browser-87.0b4-10.5-1] Bug 40073: Disable remote Public Suffix List fetching
by sysrqb@torproject.org 11 Mar '21

11 Mar '21
commit 4ef99259a6ecab53ee51955a8c3e8c22f642d7be Author: Alex Catarineu <acat(a)torproject.org> Date: Thu Aug 13 11:05:03 2020 +0200 Bug 40073: Disable remote Public Suffix List fetching In https://bugzilla.mozilla.org/show_bug.cgi?id=1563246 Firefox implemented fetching the Public Suffix List via RemoteSettings and replacing the default one at runtime, which we do not want. --- browser/components/BrowserGlue.jsm | 5 ----- 1 file changed, 5 deletions(-) diff --git a/browser/components/BrowserGlue.jsm b/browser/components/BrowserGlue.jsm index 852ade49b50f..4bfdfc88c951 100644 --- a/browser/components/BrowserGlue.jsm +++ b/browser/components/BrowserGlue.jsm @@ -67,7 +67,6 @@ XPCOMUtils.defineLazyModuleGetters(this, { PluralForm: "resource://gre/modules/PluralForm.jsm", PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm", ProcessHangMonitor: "resource:///modules/ProcessHangMonitor.jsm", - PublicSuffixList: "resource://gre/modules/netwerk-dns/PublicSuffixList.jsm", RemoteSettings: "resource://services-settings/remote-settings.js", RemoteSecuritySettings: "resource://gre/modules/psm/RemoteSecuritySettings.jsm", @@ -2761,10 +2760,6 @@ BrowserGlue.prototype = { this._addBreachesSyncHandler(); }, - () => { - PublicSuffixList.init(); - }, - () => { RemoteSecuritySettings.init(); },
1 0
0 0
[tor-browser/tor-browser-87.0b4-10.5-1] Bug 21952: Implement Onion-Location
by sysrqb@torproject.org 11 Mar '21

11 Mar '21
commit 89afde918e258a8a45a2103c02b4211e8bee8f00 Author: Alex Catarineu <acat(a)torproject.org> Date: Thu Mar 5 22:16:39 2020 +0100 Bug 21952: Implement Onion-Location Whenever a valid Onion-Location HTTP header (or corresponding HTML <meta> http-equiv attribute) is found in a document load, we either redirect to it (if the user opted-in via preference) or notify the presence of an onionsite alternative with a badge in the urlbar. --- browser/base/content/browser.js | 12 ++ browser/base/content/browser.xhtml | 3 + browser/components/BrowserGlue.jsm | 13 ++ .../onionservices/OnionLocationChild.jsm | 39 +++++ .../onionservices/OnionLocationParent.jsm | 168 +++++++++++++++++++++ .../content/onionlocation-notification-icons.css | 5 + .../onionservices/content/onionlocation-urlbar.css | 27 ++++ .../content/onionlocation-urlbar.inc.xhtml | 10 ++ .../onionservices/content/onionlocation.svg | 3 + .../content/onionlocationPreferences.inc.xhtml | 11 ++ .../content/onionlocationPreferences.js | 31 ++++ browser/components/onionservices/jar.mn | 2 + browser/components/onionservices/moz.build | 2 + browser/components/preferences/privacy.inc.xhtml | 2 + browser/components/preferences/privacy.js | 17 +++ browser/themes/shared/notification-icons.inc.css | 2 + browser/themes/shared/urlbar-searchbar.inc.css | 2 + dom/base/Document.cpp | 34 ++++- dom/base/Document.h | 2 + dom/webidl/Document.webidl | 9 ++ modules/libpref/init/StaticPrefList.yaml | 5 + xpcom/ds/StaticAtoms.py | 1 + 22 files changed, 399 insertions(+), 1 deletion(-) diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 529e742e4ff0..18a0efa78517 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -49,6 +49,7 @@ XPCOMUtils.defineLazyModuleGetters(this, { NetUtil: "resource://gre/modules/NetUtil.jsm", NewTabUtils: "resource://gre/modules/NewTabUtils.jsm", OpenInTabsUtils: "resource:///modules/OpenInTabsUtils.jsm", + OnionLocationParent: "resource:///modules/OnionLocationParent.jsm", PageActions: "resource:///modules/PageActions.jsm", PageThumbs: "resource://gre/modules/PageThumbs.jsm", PanelMultiView: "resource:///modules/PanelMultiView.jsm", @@ -5289,6 +5290,7 @@ var XULBrowserWindow = { Services.obs.notifyObservers(null, "touchbar-location-change", location); UpdateBackForwardCommands(gBrowser.webNavigation); AboutReaderParent.updateReaderButton(gBrowser.selectedBrowser); + OnionLocationParent.updateOnionLocationBadge(gBrowser.selectedBrowser); if (!gMultiProcessBrowser) { // Bug 1108553 - Cannot rotate images with e10s @@ -5781,6 +5783,16 @@ var CombinedStopReload = { var TabsProgressListener = { onStateChange(aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) { + // Clear OnionLocation UI + if ( + aStateFlags & Ci.nsIWebProgressListener.STATE_START && + aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK && + aRequest && + aWebProgress.isTopLevel + ) { + OnionLocationParent.onStateChange(aBrowser); + } + // Collect telemetry data about tab load times. if ( aWebProgress.isTopLevel && diff --git a/browser/base/content/browser.xhtml b/browser/base/content/browser.xhtml index 39ccb0c4244e..810e5981a19f 100644 --- a/browser/base/content/browser.xhtml +++ b/browser/base/content/browser.xhtml @@ -2028,6 +2028,9 @@ onclick="FullZoom.reset(); FullZoom.resetScalingZoom();" tooltip="dynamic-shortcut-tooltip" hidden="true"/> + +#include ../../components/onionservices/content/onionlocation-urlbar.inc.xhtml + <box id="pageActionSeparator" class="urlbar-page-action"/> <image id="pageActionButton" class="urlbar-icon urlbar-page-action" diff --git a/browser/components/BrowserGlue.jsm b/browser/components/BrowserGlue.jsm index ba240f4f83c1..852ade49b50f 100644 --- a/browser/components/BrowserGlue.jsm +++ b/browser/components/BrowserGlue.jsm @@ -543,6 +543,19 @@ let JSWINDOWACTORS = { allFrames: true, }, + OnionLocation: { + parent: { + moduleURI: "resource:///modules/OnionLocationParent.jsm", + }, + child: { + moduleURI: "resource:///modules/OnionLocationChild.jsm", + events: { + pageshow: { mozSystemGroup: true }, + }, + }, + messageManagerGroups: ["browsers"], + }, + PageInfo: { child: { moduleURI: "resource:///actors/PageInfoChild.jsm", diff --git a/browser/components/onionservices/OnionLocationChild.jsm b/browser/components/onionservices/OnionLocationChild.jsm new file mode 100644 index 000000000000..9e00054ac56c --- /dev/null +++ b/browser/components/onionservices/OnionLocationChild.jsm @@ -0,0 +1,39 @@ +// Copyright (c) 2020, The Tor Project, Inc. + +"use strict"; + +var EXPORTED_SYMBOLS = ["OnionLocationChild"]; + +class OnionLocationChild extends JSWindowActorChild { + handleEvent(event) { + this.onPageShow(event); + } + + onPageShow(event) { + if (event.target != this.document) { + return; + } + const onionLocationURI = this.document.onionLocationURI; + if (onionLocationURI) { + this.sendAsyncMessage("OnionLocation:Set"); + } + } + + receiveMessage(aMessage) { + if (aMessage.name == "OnionLocation:Refresh") { + const doc = this.document; + const docShell = this.docShell; + const onionLocationURI = doc.onionLocationURI; + const refreshURI = docShell.QueryInterface(Ci.nsIRefreshURI); + if (onionLocationURI && refreshURI) { + refreshURI.refreshURI( + onionLocationURI, + doc.nodePrincipal, + 0, + false, + true + ); + } + } + } +} diff --git a/browser/components/onionservices/OnionLocationParent.jsm b/browser/components/onionservices/OnionLocationParent.jsm new file mode 100644 index 000000000000..f6250e554862 --- /dev/null +++ b/browser/components/onionservices/OnionLocationParent.jsm @@ -0,0 +1,168 @@ +// Copyright (c) 2020, The Tor Project, Inc. + +"use strict"; + +var EXPORTED_SYMBOLS = ["OnionLocationParent"]; + +const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); +const { TorStrings } = ChromeUtils.import("resource:///modules/TorStrings.jsm"); + +// Prefs +const NOTIFICATION_PREF = "privacy.prioritizeonions.showNotification"; +const PRIORITIZE_ONIONS_PREF = "privacy.prioritizeonions.enabled"; + +// Element IDs +const ONIONLOCATION_BOX_ID = "onion-location-box"; +const ONIONLOCATION_BUTTON_ID = "onion-location-button"; +const ONIONLOCATION_LABEL_ID = "onion-label"; + +// Notification IDs +const NOTIFICATION_ID = "onion-location"; +const NOTIFICATION_ANCHOR_ID = "onionlocation"; + +// Strings +const STRING_ONION_AVAILABLE = TorStrings.onionLocation.onionAvailable; +const NOTIFICATION_CANCEL_LABEL = TorStrings.onionLocation.notNow; +const NOTIFICATION_CANCEL_ACCESSKEY = TorStrings.onionLocation.notNowAccessKey; +const NOTIFICATION_OK_LABEL = TorStrings.onionLocation.alwaysPrioritize; +const NOTIFICATION_OK_ACCESSKEY = + TorStrings.onionLocation.alwaysPrioritizeAccessKey; +const NOTIFICATION_TITLE = TorStrings.onionLocation.tryThis; +const NOTIFICATION_DESCRIPTION = TorStrings.onionLocation.description; +const NOTIFICATION_LEARN_MORE_URL = TorStrings.onionLocation.learnMoreURL; + +class OnionLocationParent extends JSWindowActorParent { + // Listeners are added in BrowserGlue.jsm + receiveMessage(aMsg) { + switch (aMsg.name) { + case "OnionLocation:Set": + let browser = this.browsingContext.embedderElement; + OnionLocationParent.setOnionLocation(browser); + break; + } + } + + static buttonClick(event) { + if (event.button !== 0) { + return; + } + const win = event.target.ownerGlobal; + if (win.gBrowser) { + const browser = win.gBrowser.selectedBrowser; + OnionLocationParent.redirect(browser); + } + } + + static redirect(browser) { + let windowGlobal = browser.browsingContext.currentWindowGlobal; + let actor = windowGlobal.getActor("OnionLocation"); + if (actor) { + actor.sendAsyncMessage("OnionLocation:Refresh", {}); + OnionLocationParent.setDisabled(browser); + } + } + + static onStateChange(browser) { + delete browser._onionLocation; + OnionLocationParent.hideNotification(browser); + } + + static setOnionLocation(browser) { + browser._onionLocation = true; + let tabBrowser = browser.getTabBrowser(); + if (tabBrowser && browser === tabBrowser.selectedBrowser) { + OnionLocationParent.updateOnionLocationBadge(browser); + } + } + + static hideNotification(browser) { + const win = browser.ownerGlobal; + if (browser._onionLocationPrompt) { + win.PopupNotifications.remove(browser._onionLocationPrompt); + } + } + + static showNotification(browser) { + const mustShow = Services.prefs.getBoolPref(NOTIFICATION_PREF, true); + if (!mustShow) { + return; + } + + const win = browser.ownerGlobal; + Services.prefs.setBoolPref(NOTIFICATION_PREF, false); + + const mainAction = { + label: NOTIFICATION_OK_LABEL, + accessKey: NOTIFICATION_OK_ACCESSKEY, + callback() { + Services.prefs.setBoolPref(PRIORITIZE_ONIONS_PREF, true); + OnionLocationParent.redirect(browser); + win.openPreferences("privacy-onionservices"); + }, + }; + + const cancelAction = { + label: NOTIFICATION_CANCEL_LABEL, + accessKey: NOTIFICATION_CANCEL_ACCESSKEY, + callback: () => {}, + }; + + const options = { + autofocus: true, + persistent: true, + removeOnDismissal: false, + eventCallback(aTopic) { + if (aTopic === "removed") { + delete browser._onionLocationPrompt; + delete browser.onionpopupnotificationanchor; + } + }, + learnMoreURL: NOTIFICATION_LEARN_MORE_URL, + displayURI: { + hostPort: NOTIFICATION_TITLE, // This is hacky, but allows us to have a title without extra markup/css. + }, + hideClose: true, + popupIconClass: "onionlocation-notification-icon", + }; + + // A hacky way of setting the popup anchor outside the usual url bar icon box + // onionlocationpopupnotificationanchor comes from `${ANCHOR_ID}popupnotificationanchor` + // From https://searchfox.org/mozilla-esr68/rev/080f9ed47742644d2ff84f7aa0b10aea5c4… + browser.onionlocationpopupnotificationanchor = win.document.getElementById( + ONIONLOCATION_BUTTON_ID + ); + + browser._onionLocationPrompt = win.PopupNotifications.show( + browser, + NOTIFICATION_ID, + NOTIFICATION_DESCRIPTION, + NOTIFICATION_ANCHOR_ID, + mainAction, + [cancelAction], + options + ); + } + + static setEnabled(browser) { + const win = browser.ownerGlobal; + const label = win.document.getElementById(ONIONLOCATION_LABEL_ID); + label.textContent = STRING_ONION_AVAILABLE; + const elem = win.document.getElementById(ONIONLOCATION_BOX_ID); + elem.removeAttribute("hidden"); + } + + static setDisabled(browser) { + const win = browser.ownerGlobal; + const elem = win.document.getElementById(ONIONLOCATION_BOX_ID); + elem.setAttribute("hidden", true); + } + + static updateOnionLocationBadge(browser) { + if (browser._onionLocation) { + OnionLocationParent.setEnabled(browser); + OnionLocationParent.showNotification(browser); + } else { + OnionLocationParent.setDisabled(browser); + } + } +} diff --git a/browser/components/onionservices/content/onionlocation-notification-icons.css b/browser/components/onionservices/content/onionlocation-notification-icons.css new file mode 100644 index 000000000000..7c8a6d892c6f --- /dev/null +++ b/browser/components/onionservices/content/onionlocation-notification-icons.css @@ -0,0 +1,5 @@ +/* Copyright (c) 2020, The Tor Project, Inc. */ + +.onionlocation-notification-icon { + display: none; +} \ No newline at end of file diff --git a/browser/components/onionservices/content/onionlocation-urlbar.css b/browser/components/onionservices/content/onionlocation-urlbar.css new file mode 100644 index 000000000000..91cad5f178d1 --- /dev/null +++ b/browser/components/onionservices/content/onionlocation-urlbar.css @@ -0,0 +1,27 @@ +/* Copyright (c) 2020, The Tor Project, Inc. */ + +#onion-location-button { + list-style-image: url(chrome://browser/content/onionservices/onionlocation.svg); +} + +#onion-location-box { + border-radius: 3px; + background-color: #6200A4; + padding-left: 5px; + padding-right: 5px; + color: white; + -moz-context-properties: fill; + fill: white; +} + +#onion-location-box:hover { + background-color: #0060DF !important; +} + +toolbar[brighttext] #onion-location-box { + background-color: #9400ff; +} + +toolbar[brighttext] #onion-location-box:hover { + background-color: #0060DF !important; +} diff --git a/browser/components/onionservices/content/onionlocation-urlbar.inc.xhtml b/browser/components/onionservices/content/onionlocation-urlbar.inc.xhtml new file mode 100644 index 000000000000..b612a4236f3c --- /dev/null +++ b/browser/components/onionservices/content/onionlocation-urlbar.inc.xhtml @@ -0,0 +1,10 @@ +# Copyright (c) 2020, The Tor Project, Inc. + +<hbox id="onion-location-box" + class="urlbar-icon-wrapper urlbar-page-action" + role="button" + hidden="true" + onclick="OnionLocationParent.buttonClick(event);"> + <image id="onion-location-button" role="presentation"/> + <hbox id="onion-label-container"><label id="onion-label"/></hbox> +</hbox> diff --git a/browser/components/onionservices/content/onionlocation.svg b/browser/components/onionservices/content/onionlocation.svg new file mode 100644 index 000000000000..37f40ac1812f --- /dev/null +++ b/browser/components/onionservices/content/onionlocation.svg @@ -0,0 +1,3 @@ +<svg width="16" height="16" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <path fill="context-fill" fill-opacity="context-fill-opacity" d="m8.016411 14.54499v-0.969784c3.071908-0.0089 5.559239-2.501304 5.559239-5.575429 0-3.073903-2.487331-5.566336-5.559239-5.575206v-0.9697843c3.607473 0.00909 6.528802 2.935521 6.528802 6.544991 0 3.609691-2.921329 6.536342-6.528802 6.545213zm0-3.394356c1.732661-0.0091 3.135111-1.415756 3.135111-3.150857 0-1.734878-1.402451-3.141542-3.135111-3.150634v-0.9695626c2.268448 0.00887 4.104895 1.849753 4.104895 4.120197 0 2.270666-1.836447 4.111549-4.104895 4.120419zm0-4.846926c0.9294227 0.00887 1.680545 0.7644289 1.680545 1.696069 0 0.9318627-0.7511226 1.687421-1.680545 1.696291zm-8.016411 1.696069c0 4.418473 3.581527 8.000222 8 8.000222 4.418251 0 8-3.581749 8-8.000222 0-4.418251-3.581749-7.999778-8-7.999778-4.418473 0-8 3.581527-8 7.999778z" /> +</svg> \ No newline at end of file diff --git a/browser/components/onionservices/content/onionlocationPreferences.inc.xhtml b/browser/components/onionservices/content/onionlocationPreferences.inc.xhtml new file mode 100644 index 000000000000..c285f403f99b --- /dev/null +++ b/browser/components/onionservices/content/onionlocationPreferences.inc.xhtml @@ -0,0 +1,11 @@ +# Copyright (c) 2020, The Tor Project, Inc. + +<groupbox id="onionServicesGroup" data-category="panePrivacy" data-subcategory="onionservices" hidden="true"> + <label><html:h2 id="onionServicesTitle"></html:h2></label> + <label><label class="tail-with-learn-more" id="prioritizeOnionsDesc"></label><label + class="learnMore" is="text-link" id="onionServicesLearnMore"></label></label> + <radiogroup id="prioritizeOnionsRadioGroup" aria-labelledby="prioritizeOnionsDesc" preference="privacy.prioritizeonions.enabled"> + <radio id="onionServicesRadioAlways" value="true"/> + <radio id="onionServicesRadioAsk" value="false"/> + </radiogroup> +</groupbox> diff --git a/browser/components/onionservices/content/onionlocationPreferences.js b/browser/components/onionservices/content/onionlocationPreferences.js new file mode 100644 index 000000000000..aa569b54721c --- /dev/null +++ b/browser/components/onionservices/content/onionlocationPreferences.js @@ -0,0 +1,31 @@ +// Copyright (c) 2020, The Tor Project, Inc. + +"use strict"; + +ChromeUtils.defineModuleGetter( + this, + "TorStrings", + "resource:///modules/TorStrings.jsm" +); + +const OnionLocationPreferences = { + init() { + document.getElementById("onionServicesTitle").textContent = + TorStrings.onionLocation.onionServicesTitle; + document.getElementById("prioritizeOnionsDesc").textContent = + TorStrings.onionLocation.prioritizeOnionsDescription; + const learnMore = document.getElementById("onionServicesLearnMore"); + learnMore.textContent = TorStrings.onionLocation.learnMore; + learnMore.href = TorStrings.onionLocation.learnMoreURL; + document.getElementById("onionServicesRadioAlways").label = + TorStrings.onionLocation.always; + document.getElementById("onionServicesRadioAsk").label = + TorStrings.onionLocation.askEverytime; + }, +}; + +Object.defineProperty(this, "OnionLocationPreferences", { + value: OnionLocationPreferences, + enumerable: true, + writable: false, +}); diff --git a/browser/components/onionservices/jar.mn b/browser/components/onionservices/jar.mn index 9d6ce88d1841..f45b16dc5d29 100644 --- a/browser/components/onionservices/jar.mn +++ b/browser/components/onionservices/jar.mn @@ -7,3 +7,5 @@ browser.jar: content/browser/onionservices/onionservices.css (content/onionservices.css) content/browser/onionservices/savedKeysDialog.js (content/savedKeysDialog.js) content/browser/onionservices/savedKeysDialog.xhtml (content/savedKeysDialog.xhtml) + content/browser/onionservices/onionlocationPreferences.js (content/onionlocationPreferences.js) + content/browser/onionservices/onionlocation.svg (content/onionlocation.svg) diff --git a/browser/components/onionservices/moz.build b/browser/components/onionservices/moz.build index 815685322024..8027233d65a6 100644 --- a/browser/components/onionservices/moz.build +++ b/browser/components/onionservices/moz.build @@ -4,4 +4,6 @@ EXTRA_JS_MODULES += [ "ExtensionMessaging.jsm", "HttpsEverywhereControl.jsm", "OnionAliasStore.jsm", + "OnionLocationChild.jsm", + "OnionLocationParent.jsm", ] diff --git a/browser/components/preferences/privacy.inc.xhtml b/browser/components/preferences/privacy.inc.xhtml index cb39d058438d..abaa1561dd47 100644 --- a/browser/components/preferences/privacy.inc.xhtml +++ b/browser/components/preferences/privacy.inc.xhtml @@ -14,6 +14,8 @@ <html:h1 data-l10n-id="privacy-header"/> </hbox> +#include ../onionservices/content/onionlocationPreferences.inc.xhtml + <!-- Tracking / Content Blocking --> <groupbox id="trackingGroup" data-category="panePrivacy" hidden="true" aria-describedby="contentBlockingDescription"> <label id="contentBlockingHeader"><html:h2 data-l10n-id="content-blocking-enhanced-tracking-protection"/></label> diff --git a/browser/components/preferences/privacy.js b/browser/components/preferences/privacy.js index 6b3f05877e5c..7c2ff42e4808 100644 --- a/browser/components/preferences/privacy.js +++ b/browser/components/preferences/privacy.js @@ -93,6 +93,12 @@ XPCOMUtils.defineLazyScriptGetter( "chrome://browser/content/securitylevel/securityLevel.js" ); +XPCOMUtils.defineLazyScriptGetter( + this, + ["OnionLocationPreferences"], + "chrome://browser/content/onionservices/onionlocationPreferences.js" +); + XPCOMUtils.defineLazyServiceGetter( this, "listManager", @@ -169,6 +175,9 @@ Preferences.addAll([ // Do not track { id: "privacy.donottrackheader.enabled", type: "bool" }, + // Onion Location + { id: "privacy.prioritizeonions.enabled", type: "bool" }, + // Media { id: "media.autoplay.default", type: "int" }, @@ -330,6 +339,13 @@ var gPrivacyPane = { window.addEventListener("unload", unload); }, + /** + * Show the OnionLocation preferences UI + */ + _initOnionLocation() { + OnionLocationPreferences.init(); + }, + /** * Whether the prompt to restart Firefox should appear when changing the autostart pref. */ @@ -531,6 +547,7 @@ var gPrivacyPane = { this._initTrackingProtectionExtensionControl(); OnionServicesAuthPreferences.init(); this._initSecurityLevel(); + this._initOnionLocation(); Services.telemetry.setEventRecordingEnabled("pwmgr", true); diff --git a/browser/themes/shared/notification-icons.inc.css b/browser/themes/shared/notification-icons.inc.css index 907c492e7761..55ae55b555d3 100644 --- a/browser/themes/shared/notification-icons.inc.css +++ b/browser/themes/shared/notification-icons.inc.css @@ -427,3 +427,5 @@ html|*#webRTC-previewVideo { background: #FFE900 url(chrome://browser/skin/notification-icons/update.svg) no-repeat center; border-radius: 50%; } + +%include ../../components/onionservices/content/onionlocation-notification-icons.css \ No newline at end of file diff --git a/browser/themes/shared/urlbar-searchbar.inc.css b/browser/themes/shared/urlbar-searchbar.inc.css index a01ddee72abf..5fe267ae25e0 100644 --- a/browser/themes/shared/urlbar-searchbar.inc.css +++ b/browser/themes/shared/urlbar-searchbar.inc.css @@ -948,3 +948,5 @@ .searchbar-search-button:hover:not([addengines=true]) > .searchbar-search-icon-overlay:-moz-locale-dir(rtl) { margin-inline: -26px 20px; } + +%include ../../components/onionservices/content/onionlocation-urlbar.css diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp index 48af2c30f360..b87c1d449033 100644 --- a/dom/base/Document.cpp +++ b/dom/base/Document.cpp @@ -2790,6 +2790,7 @@ void Document::ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup, // mDocumentURI. mDocumentBaseURI = nullptr; mChromeXHRDocBaseURI = nullptr; + mOnionLocationURI = nullptr; // Check if the current document is the top-level DevTools document. // For inner DevTools frames, mIsDevToolsDocument will be set when @@ -6304,6 +6305,22 @@ void Document::GetHeaderData(nsAtom* aHeaderField, nsAString& aData) const { } } +static bool IsValidOnionLocation(nsIURI* aDocumentURI, + nsIURI* aOnionLocationURI) { + bool isHttpish; + nsAutoCString host; + return aDocumentURI && aOnionLocationURI && + NS_SUCCEEDED(aDocumentURI->SchemeIs("https", &isHttpish)) && + isHttpish && NS_SUCCEEDED(aDocumentURI->GetAsciiHost(host)) && + !StringEndsWith(host, ".onion"_ns) && + ((NS_SUCCEEDED(aOnionLocationURI->SchemeIs("http", &isHttpish)) && + isHttpish) || + (NS_SUCCEEDED(aOnionLocationURI->SchemeIs("https", &isHttpish)) && + isHttpish)) && + NS_SUCCEEDED(aOnionLocationURI->GetAsciiHost(host)) && + StringEndsWith(host, ".onion"_ns); +} + void Document::SetHeaderData(nsAtom* aHeaderField, const nsAString& aData) { if (!aHeaderField) { NS_ERROR("null headerField"); @@ -6378,6 +6395,21 @@ void Document::SetHeaderData(nsAtom* aHeaderField, const nsAString& aData) { aHeaderField == nsGkAtoms::handheldFriendly) { mViewportType = Unknown; } + + if (aHeaderField == nsGkAtoms::headerOnionLocation && !aData.IsEmpty()) { + nsCOMPtr<nsIURI> onionURI; + if (NS_SUCCEEDED(NS_NewURI(getter_AddRefs(onionURI), aData)) && + IsValidOnionLocation(Document::GetDocumentURI(), onionURI)) { + if (StaticPrefs::privacy_prioritizeonions_enabled()) { + nsCOMPtr<nsIRefreshURI> refresher(mDocumentContainer); + if (refresher) { + refresher->RefreshURI(onionURI, NodePrincipal(), 0, false, true); + } + } else { + mOnionLocationURI = onionURI; + } + } + } } void Document::TryChannelCharset(nsIChannel* aChannel, int32_t& aCharsetSource, @@ -10440,7 +10472,7 @@ void Document::RetrieveRelevantHeaders(nsIChannel* aChannel) { static const char* const headers[] = { "default-style", "content-style-type", "content-language", "content-disposition", "refresh", "x-dns-prefetch-control", - "x-frame-options", + "x-frame-options", "onion-location", // add more http headers if you need // XXXbz don't add content-location support without reading bug // 238654 and its dependencies/dups first. diff --git a/dom/base/Document.h b/dom/base/Document.h index b0ac1f1ca7d1..374d5d6c8d3a 100644 --- a/dom/base/Document.h +++ b/dom/base/Document.h @@ -3390,6 +3390,7 @@ class Document : public nsINode, void ReleaseCapture() const; void MozSetImageElement(const nsAString& aImageElementId, Element* aElement); nsIURI* GetDocumentURIObject() const; + nsIURI* GetOnionLocationURI() const { return mOnionLocationURI; } // Not const because all the fullscreen goop is not const const char* GetFullscreenError(CallerType); bool FullscreenEnabled(CallerType aCallerType) { @@ -4316,6 +4317,7 @@ class Document : public nsINode, nsCOMPtr<nsIURI> mChromeXHRDocURI; nsCOMPtr<nsIURI> mDocumentBaseURI; nsCOMPtr<nsIURI> mChromeXHRDocBaseURI; + nsCOMPtr<nsIURI> mOnionLocationURI; // The base domain of the document for third-party checks. nsCString mBaseDomain; diff --git a/dom/webidl/Document.webidl b/dom/webidl/Document.webidl index abb7b6b0b435..5e68056473a7 100644 --- a/dom/webidl/Document.webidl +++ b/dom/webidl/Document.webidl @@ -702,3 +702,12 @@ partial interface Document { [ChromeOnly, Pure] readonly attribute nsIPermissionDelegateHandler permDelegateHandler; }; + + +/** + * Extension to allows chrome JS to know whether the document has a valid + * Onion-Location that we could redirect to. + */ +partial interface Document { + [ChromeOnly] readonly attribute URI? onionLocationURI; +}; diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml index 43c899a1682a..8d3a3fd38f9f 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -9494,6 +9494,11 @@ value: false mirror: always +- name: privacy.prioritizeonions.enabled + type: RelaxedAtomicBool + value: false + mirror: always + #--------------------------------------------------------------------------- # Prefs starting with "prompts." #--------------------------------------------------------------------------- diff --git a/xpcom/ds/StaticAtoms.py b/xpcom/ds/StaticAtoms.py index 4c4a8b21c8f5..92b97d959f45 100644 --- a/xpcom/ds/StaticAtoms.py +++ b/xpcom/ds/StaticAtoms.py @@ -816,6 +816,7 @@ STATIC_ATOMS = [ Atom("oninputsourceschange", "oninputsourceschange"), Atom("oninstall", "oninstall"), Atom("oninvalid", "oninvalid"), + Atom("headerOnionLocation", "onion-location"), Atom("onkeydown", "onkeydown"), Atom("onkeypress", "onkeypress"), Atom("onkeyup", "onkeyup"),
1 0
0 0
[tor-browser/tor-browser-87.0b4-10.5-1] Bug 40309: Avoid using regional OS locales
by sysrqb@torproject.org 11 Mar '21

11 Mar '21
commit 73e2ccfc12c067c49bd02e0505c80efd94207c87 Author: Alex Catarineu <acat(a)torproject.org> Date: Wed Jan 27 11:28:05 2021 +0100 Bug 40309: Avoid using regional OS locales Only use regional OS locales if the pref `intl.regional_prefs.use_os_locales` is set to true. --- intl/locale/LocaleService.cpp | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/intl/locale/LocaleService.cpp b/intl/locale/LocaleService.cpp index 929b235235a3..1132d399b1d4 100644 --- a/intl/locale/LocaleService.cpp +++ b/intl/locale/LocaleService.cpp @@ -459,31 +459,6 @@ LocaleService::GetRegionalPrefsLocales(nsTArray<nsCString>& aRetVal) { OSPreferences::GetInstance()->GetRegionalPrefsLocales(aRetVal))) { return NS_OK; } - - // If we fail to retrieve them, return the app locales. - GetAppLocalesAsBCP47(aRetVal); - return NS_OK; - } - - // Otherwise, fetch OS Regional Preferences locales and compare the first one - // to the app locale. If the language subtag matches, we can safely use - // the OS Regional Preferences locale. - // - // This facilitates scenarios such as Firefox in "en-US" and User sets - // regional prefs to "en-GB". - nsAutoCString appLocale; - AutoTArray<nsCString, 10> regionalPrefsLocales; - LocaleService::GetInstance()->GetAppLocaleAsBCP47(appLocale); - - if (NS_FAILED(OSPreferences::GetInstance()->GetRegionalPrefsLocales( - regionalPrefsLocales))) { - GetAppLocalesAsBCP47(aRetVal); - return NS_OK; - } - - if (LocaleService::LanguagesMatch(appLocale, regionalPrefsLocales[0])) { - aRetVal = regionalPrefsLocales.Clone(); - return NS_OK; } // Otherwise use the app locales.
1 0
0 0
[tor-browser/tor-browser-87.0b4-10.5-1] Bug 33852: Clean up about:logins (LockWise) to avoid mentioning sync, etc.
by sysrqb@torproject.org 11 Mar '21

11 Mar '21
commit 3d9876c1e3efce399b330f6a187f69dba49d10c6 Author: Kathy Brade <brade(a)pearlcrescent.com> Date: Tue Jul 14 11:15:07 2020 -0400 Bug 33852: Clean up about:logins (LockWise) to avoid mentioning sync, etc. Hide elements on about:logins that mention sync, "Firefox LockWise", and Mozilla's LockWise mobile apps. Disable the "Create New Login" button when security.nocertdb is true. --- browser/components/aboutlogins/AboutLoginsParent.jsm | 2 ++ browser/components/aboutlogins/content/aboutLogins.css | 8 +++++++- browser/components/aboutlogins/content/aboutLogins.js | 6 ++++++ .../aboutlogins/content/components/fxaccounts-button.css | 5 +++++ .../components/aboutlogins/content/components/menu-button.css | 10 ++++++++++ 5 files changed, 30 insertions(+), 1 deletion(-) diff --git a/browser/components/aboutlogins/AboutLoginsParent.jsm b/browser/components/aboutlogins/AboutLoginsParent.jsm index a157e10530c5..a6c937d2b850 100644 --- a/browser/components/aboutlogins/AboutLoginsParent.jsm +++ b/browser/components/aboutlogins/AboutLoginsParent.jsm @@ -65,6 +65,7 @@ const PASSWORD_SYNC_NOTIFICATION_ID = "enable-password-sync"; const SHOW_PASSWORD_SYNC_NOTIFICATION_PREF = "signon.management.page.showPasswordSyncNotification"; +const NOCERTDB_PREF = "security.nocertdb"; // about:logins will always use the privileged content process, // even if it is disabled for other consumers such as about:newtab. @@ -281,6 +282,7 @@ class AboutLoginsParent extends JSWindowActorParent { importVisible: Services.policies.isAllowed("profileImport") && AppConstants.platform != "linux", + canCreateLogins: !Services.prefs.getBoolPref(NOCERTDB_PREF, false), }); await AboutLogins._sendAllLoginRelatedObjects( diff --git a/browser/components/aboutlogins/content/aboutLogins.css b/browser/components/aboutlogins/content/aboutLogins.css index 79d46c336cc9..d3dd02f80b89 100644 --- a/browser/components/aboutlogins/content/aboutLogins.css +++ b/browser/components/aboutlogins/content/aboutLogins.css @@ -69,6 +69,11 @@ login-item { grid-area: login; } +/* Do not promote Mozilla Sync in Tor Browser. */ +login-intro { + display: none !important; +} + #branding-logo { flex-basis: var(--sidebar-width); flex-shrink: 0; @@ -83,7 +88,8 @@ login-item { } } -:root:not(.official-branding) #branding-logo { +/* Hide "Firefox LockWise" branding in Tor Browser. */ +#branding-logo { visibility: hidden; } diff --git a/browser/components/aboutlogins/content/aboutLogins.js b/browser/components/aboutlogins/content/aboutLogins.js index a7449f8343b3..f288fb6988fb 100644 --- a/browser/components/aboutlogins/content/aboutLogins.js +++ b/browser/components/aboutlogins/content/aboutLogins.js @@ -22,6 +22,9 @@ const gElements = { ".menuitem-remove-all-logins" ); }, + get createNewLoginButton() { + return this.loginList.shadowRoot.querySelector(".create-login-button"); + }, }; let numberOfLogins = 0; @@ -111,6 +114,9 @@ window.addEventListener("AboutLoginsChromeToContent", event => { gElements.loginList.setSortDirection(event.detail.value.selectedSort); document.documentElement.classList.add("initialized"); gElements.loginList.classList.add("initialized"); + if (!event.detail.value.canCreateLogins) { + gElements.createNewLoginButton.disabled = true; + } break; } case "ShowLoginItemError": { diff --git a/browser/components/aboutlogins/content/components/fxaccounts-button.css b/browser/components/aboutlogins/content/components/fxaccounts-button.css index e63192a98e3a..c59eda2dec56 100644 --- a/browser/components/aboutlogins/content/components/fxaccounts-button.css +++ b/browser/components/aboutlogins/content/components/fxaccounts-button.css @@ -8,6 +8,11 @@ align-items: center; } +/* Do not promote Mozilla Sync in Tor Browser. */ +.logged-out-view { + display: none !important; +} + .fxaccounts-extra-text { /* Only show at most 3 lines of text to limit the text from overflowing the header. */ diff --git a/browser/components/aboutlogins/content/components/menu-button.css b/browser/components/aboutlogins/content/components/menu-button.css index 840322d9fbdb..0c8631c6874b 100644 --- a/browser/components/aboutlogins/content/components/menu-button.css +++ b/browser/components/aboutlogins/content/components/menu-button.css @@ -85,3 +85,13 @@ .menuitem-preferences { background-image: url("chrome://global/skin/icons/settings.svg"); } + +/* + * Do not promote LockWise mobile apps in Tor Browser: hide the menu items + * and the separator line that precedes them. + */ +.menuitem-mobile-android, +.menuitem-mobile-ios, +button[data-event-name="AboutLoginsGetHelp"] + hr { + display: none !important; +}
1 0
0 0
[tor-browser/tor-browser-87.0b4-10.5-1] Bug 40125: Expose Security Level pref in GeckoView
by sysrqb@torproject.org 11 Mar '21

11 Mar '21
commit 0bfbfec100fc85a85913d3df2e4a75d0bdd3aa47 Author: Matthew Finkel <sysrqb(a)torproject.org> Date: Mon Sep 14 02:52:28 2020 +0000 Bug 40125: Expose Security Level pref in GeckoView --- mobile/android/geckoview/api.txt | 3 ++ .../mozilla/geckoview/GeckoRuntimeSettings.java | 33 ++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/mobile/android/geckoview/api.txt b/mobile/android/geckoview/api.txt index ca7fe311f852..c7e82620b2a6 100644 --- a/mobile/android/geckoview/api.txt +++ b/mobile/android/geckoview/api.txt @@ -641,6 +641,7 @@ package org.mozilla.geckoview { method @Nullable public GeckoRuntime getRuntime(); method @Nullable public Rect getScreenSizeOverride(); method @Nullable public RuntimeTelemetry.Delegate getTelemetryDelegate(); + method public int getTorSecurityLevel(); method public boolean getUseMaxScreenDepth(); method public boolean getWebFontsEnabled(); method public boolean getWebManifestEnabled(); @@ -659,6 +660,7 @@ package org.mozilla.geckoview { method @NonNull public GeckoRuntimeSettings setLoginAutofillEnabled(boolean); method @NonNull public GeckoRuntimeSettings setPreferredColorScheme(int); method @NonNull public GeckoRuntimeSettings setRemoteDebuggingEnabled(boolean); + method @NonNull public GeckoRuntimeSettings setTorSecurityLevel(int); method @NonNull public GeckoRuntimeSettings setWebFontsEnabled(boolean); method @NonNull public GeckoRuntimeSettings setWebManifestEnabled(boolean); field public static final int ALLOW_ALL = 0; @@ -698,6 +700,7 @@ package org.mozilla.geckoview { method @NonNull public GeckoRuntimeSettings.Builder remoteDebuggingEnabled(boolean); method @NonNull public GeckoRuntimeSettings.Builder screenSizeOverride(int, int); method @NonNull public GeckoRuntimeSettings.Builder telemetryDelegate(@NonNull RuntimeTelemetry.Delegate); + method @NonNull public GeckoRuntimeSettings.Builder torSecurityLevel(int); method @NonNull public GeckoRuntimeSettings.Builder useMaxScreenDepth(boolean); method @NonNull public GeckoRuntimeSettings.Builder webFontsEnabled(boolean); method @NonNull public GeckoRuntimeSettings.Builder webManifest(boolean); diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntimeSettings.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntimeSettings.java index a054fe3125fb..34ffde8bfdd6 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntimeSettings.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntimeSettings.java @@ -458,6 +458,17 @@ public final class GeckoRuntimeSettings extends RuntimeSettings { getSettings().setAllowInsecureConnections(level); return this; } + + /** + * Set security level. + * + * @param level A value determining the security level. Default is 0. + * @return This Builder instance. + */ + public @NonNull Builder torSecurityLevel(final int level) { + getSettings().mTorSecurityLevel.set(level); + return this; + } } private GeckoRuntime mRuntime; @@ -510,6 +521,8 @@ public final class GeckoRuntimeSettings extends RuntimeSettings { "dom.security.https_only_mode", false); /* package */ final Pref<Boolean> mHttpsOnlyPrivateMode = new Pref<Boolean>( "dom.security.https_only_mode_pbm", false); + /* package */ final Pref<Integer> mTorSecurityLevel = new Pref<>( + "extensions.torbutton.security_slider", 4); /* package */ int mPreferredColorScheme = COLOR_SCHEME_SYSTEM; @@ -1208,6 +1221,26 @@ public final class GeckoRuntimeSettings extends RuntimeSettings { return this; } + /** + * Gets the current security level. + * + * @return current security protection level + */ + public int getTorSecurityLevel() { + return mTorSecurityLevel.get(); + } + + /** + * Sets the Tor Security Level. + * + * @param level security protection level + * @return This GeckoRuntimeSettings instance. + */ + public @NonNull GeckoRuntimeSettings setTorSecurityLevel(final int level) { + mTorSecurityLevel.commit(level); + return this; + } + @Override // Parcelable public void writeToParcel(final Parcel out, final int flags) { super.writeToParcel(out, flags);
1 0
0 0
[tor-browser/tor-browser-87.0b4-10.5-1] Bug 40091: Load HTTPS Everywhere as a builtin addon in desktop
by sysrqb@torproject.org 11 Mar '21

11 Mar '21
commit 7602d29be690652bf750f23ff5388a1716c1f2c4 Author: Alex Catarineu <acat(a)torproject.org> Date: Fri Sep 4 12:34:35 2020 +0200 Bug 40091: Load HTTPS Everywhere as a builtin addon in desktop This loads HTTPS Everywhere as a builtin addon from a hardcoded resource:// URI in desktop. It also ensures that the non-builtin HTTPS Everywhere addon is always uninstalled on browser startup. The reason of making this desktop-only is that there are some issues when installing a builtin extension from geckoview side, making the extension not available on first startup. So, at least for now we handle the Fenix case separately. See #40118 for a followup for investigating these. --- browser/components/BrowserGlue.jsm | 37 ++++++++++++++++++++++ toolkit/components/extensions/Extension.jsm | 10 ++++-- .../mozapps/extensions/internal/XPIProvider.jsm | 13 ++++++++ 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/browser/components/BrowserGlue.jsm b/browser/components/BrowserGlue.jsm index 4bfdfc88c951..2e7824c0807e 100644 --- a/browser/components/BrowserGlue.jsm +++ b/browser/components/BrowserGlue.jsm @@ -42,6 +42,7 @@ XPCOMUtils.defineLazyModuleGetters(this, { DownloadsViewableInternally: "resource:///modules/DownloadsViewableInternally.jsm", E10SUtils: "resource://gre/modules/E10SUtils.jsm", + ExtensionData: "resource://gre/modules/Extension.jsm", ExtensionsUI: "resource:///modules/ExtensionsUI.jsm", ExperimentAPI: "resource://nimbus/ExperimentAPI.jsm", FeatureGate: "resource://featuregates/FeatureGate.jsm", @@ -118,6 +119,13 @@ XPCOMUtils.defineLazyServiceGetter( "nsIPushService" ); +XPCOMUtils.defineLazyServiceGetters(this, { + resProto: [ + "@mozilla.org/network/protocol;1?name=resource", + "nsISubstitutingProtocolHandler", + ], +}); + const PREF_PDFJS_ISDEFAULT_CACHE_STATE = "pdfjs.enabledCache.state"; /** @@ -1376,6 +1384,35 @@ BrowserGlue.prototype = { "resource://builtin-themes/alpenglow/" ); + // Install https-everywhere builtin addon if needed. + (async () => { + const HTTPS_EVERYWHERE_ID = "https-everywhere-eff(a)eff.org"; + const HTTPS_EVERYWHERE_BUILTIN_URL = + "resource://torbutton/content/extensions/https-everywhere/"; + // This does something similar as GeckoViewWebExtension.jsm: it tries + // to load the manifest to retrieve the version of the builtin and + // compares it to the currently installed one to see whether we need + // to install or not. Here we delegate that to + // AddonManager.maybeInstallBuiltinAddon. + try { + const resolvedURI = Services.io.newURI( + resProto.resolveURI(Services.io.newURI(HTTPS_EVERYWHERE_BUILTIN_URL)) + ); + const extensionData = new ExtensionData(resolvedURI); + const manifest = await extensionData.loadManifest(); + + await AddonManager.maybeInstallBuiltinAddon( + HTTPS_EVERYWHERE_ID, + manifest.version, + HTTPS_EVERYWHERE_BUILTIN_URL + ); + } catch (e) { + const log = Log.repository.getLogger("HttpsEverywhereBuiltinLoader"); + log.addAppender(new Log.ConsoleAppender(new Log.BasicFormatter())); + log.error("Could not install https-everywhere extension", e); + } + })(); + if (AppConstants.MOZ_NORMANDY) { Normandy.init(); } diff --git a/toolkit/components/extensions/Extension.jsm b/toolkit/components/extensions/Extension.jsm index 1b940b6d9954..d178e0a74432 100644 --- a/toolkit/components/extensions/Extension.jsm +++ b/toolkit/components/extensions/Extension.jsm @@ -212,6 +212,7 @@ const LOGGER_ID_BASE = "addons.webextension."; const UUID_MAP_PREF = "extensions.webextensions.uuids"; const LEAVE_STORAGE_PREF = "extensions.webextensions.keepStorageOnUninstall"; const LEAVE_UUID_PREF = "extensions.webextensions.keepUuidOnUninstall"; +const PERSISTENT_EXTENSIONS = new Set(["https-everywhere-eff(a)eff.org"]); const COMMENT_REGEXP = new RegExp( String.raw` @@ -358,7 +359,8 @@ var ExtensionAddonObserver = { ); } - if (!Services.prefs.getBoolPref(LEAVE_STORAGE_PREF, false)) { + if (!Services.prefs.getBoolPref(LEAVE_STORAGE_PREF, false) && + !PERSISTENT_EXTENSIONS.has(addon.id)) { // Clear browser.storage.local backends. AsyncShutdown.profileChangeTeardown.addBlocker( `Clear Extension Storage ${addon.id} (File Backend)`, @@ -406,7 +408,8 @@ var ExtensionAddonObserver = { ExtensionPermissions.removeAll(addon.id); - if (!Services.prefs.getBoolPref(LEAVE_UUID_PREF, false)) { + if (!Services.prefs.getBoolPref(LEAVE_UUID_PREF, false) && + !PERSISTENT_EXTENSIONS.has(addon.id)) { // Clear the entry in the UUID map UUIDMap.remove(addon.id); } @@ -2596,7 +2599,8 @@ class Extension extends ExtensionData { ); } else if ( this.startupReason === "ADDON_INSTALL" && - !Services.prefs.getBoolPref(LEAVE_STORAGE_PREF, false) + !Services.prefs.getBoolPref(LEAVE_STORAGE_PREF, false) && + !PERSISTENT_EXTENSIONS.has(this.id) ) { // If the extension has been just installed, set it as migrated, // because there will not be any data to migrate. diff --git a/toolkit/mozapps/extensions/internal/XPIProvider.jsm b/toolkit/mozapps/extensions/internal/XPIProvider.jsm index 0ea38bfbcb63..4b645bd7e20b 100644 --- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm +++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm @@ -1498,6 +1498,19 @@ var XPIStates = { continue; } + // Uninstall HTTPS Everywhere if it is installed in the user profile. + if ( + id === "https-everywhere-eff(a)eff.org" && + loc.name === KEY_APP_PROFILE + ) { + logger.debug( + "Uninstalling the HTTPS Everywhere extension from user profile." + ); + loc.installer.uninstallAddon(id); + changed = true; + continue; + } + let xpiState = loc.get(id); if (!xpiState) { // If the location is not supported for sideloading, skip new
1 0
0 0
[tor-browser/tor-browser-87.0b4-10.5-1] TB3: Tor Browser's official .mozconfigs.
by sysrqb@torproject.org 11 Mar '21

11 Mar '21
commit 33ee689f93da383583603f5621fcfff65bb7e856 Author: Mike Perry <mikeperry-git(a)torproject.org> Date: Mon May 6 15:51:06 2013 -0700 TB3: Tor Browser's official .mozconfigs. Also: Bug #9829.1: new .mozconfig file for the new cross-compiler and ESR24 Changes needed to build Mac in 64bit Bug 10715: Enable Webgl for mingw-w64 again. Disable ICU when cross-compiling; clean-up. Bug 15773: Enable ICU on OS X Bug 15990: Don't build the sandbox with mingw-w64 Bug 12761: Switch to ESR 38 for OS X Updating .mozconfig-asan Bug 12516: Compile hardenend Tor Browser with -fwrapv Bug 18331: Switch to Mozilla's toolchain for building Tor Browser for OS X Bug 17858: Cannot create incremental MARs for hardened builds. Define HOST_CFLAGS, etc. to avoid compiling programs such as mbsdiff (which is part of mar-tools and is not distributed to end-users) with ASan. Bug 13419: Add back ICU for Windows Bug 21239: Use GTK2 for ESR52 Linux builds Bug 23025: Add hardening flags for macOS Bug 24478: Enable debug assertions and tests in our ASan builds --enable-proxy-bypass-protection Bug 27597: ASan build option in tor-browser-build is broken Bug 27623 - Export MOZILLA_OFFICIAL during desktop builds This fixes a problem where some preferences had the wrong default value. Also see bug 27472 where we made a similar fix for Android. Bug 30463: Explicitly disable MOZ_TELEMETRY_REPORTING Bug 31450: Set proper BINDGEN_CFLAGS for ASan builds Add an --enable-tor-browser-data-outside-app-dir configure option Add --with-tor-browser-version configure option Bug 21849: Don't allow SSL key logging. Bug 31457: disable per-installation profiles The dedicated profiles (per-installation) feature does not interact well with our bundled profiles on Linux and Windows, and it also causes multiple profiles to be created on macOS under TorBrowser-Data. Bug 31935: Disable profile downgrade protection. Since Tor Browser does not support more than one profile, disable the prompt and associated code that offers to create one when a version downgrade situation is detected. Bug 32493: Disable MOZ_SERVICES_HEALTHREPORT Bug 25741 - TBA: Disable features at compile-time MOZ_NATIVE_DEVICES for casting and the media player MOZ_TELEMETRY_REPORTING for telemetry MOZ_DATA_REPORTING for all data reporting preferences (crashreport, telemetry, geo) Bug 25741 - TBA: Add default configure options in dedicated file Define MOZ_ANDROID_NETWORK_STATE and MOZ_ANDROID_LOCATION Bug 29859: Disable HLS support for now Add --disable-tor-launcher build option Add --enable-tor-browser-update build option Bug 33734: Set MOZ_NORMANDY to False Bug 33851: Omit Parental Controls. Bug 40061: Omit the Windows default browser agent from the build Bug 40211: Lower required build-tools version to 29.0.2 Bug 40252: Add --enable-rust-simd to our tor-browser mozconfig files --- .mozconfig | 39 +++++++++++++++++++++ .mozconfig-android | 36 ++++++++++++++++++++ .mozconfig-asan | 44 ++++++++++++++++++++++++ .mozconfig-mac | 56 +++++++++++++++++++++++++++++++ .mozconfig-mingw | 31 +++++++++++++++++ browser/base/moz.build | 3 ++ browser/installer/Makefile.in | 8 +++++ browser/moz.configure | 8 ++--- build/moz.configure/android-sdk.configure | 2 +- build/moz.configure/old.configure | 5 +++ mobile/android/confvars.sh | 9 +++++ mobile/android/geckoview/build.gradle | 1 + mobile/android/moz.configure | 22 ++++++++++-- mobile/android/torbrowser.configure | 30 +++++++++++++++++ old-configure.in | 49 +++++++++++++++++++++++++++ security/moz.build | 2 +- security/nss/lib/ssl/Makefile | 2 +- toolkit/modules/AppConstants.jsm | 15 +++++++++ toolkit/modules/moz.build | 3 ++ 19 files changed, 356 insertions(+), 9 deletions(-) diff --git a/.mozconfig b/.mozconfig new file mode 100755 index 000000000000..18cd1f9b6487 --- /dev/null +++ b/.mozconfig @@ -0,0 +1,39 @@ +. $topsrcdir/browser/config/mozconfig + +# This mozconfig file is not used in official Tor Browser builds. +# It is only intended to be used when doing incremental Linux builds +# during development. The platform-specific mozconfig configuration +# files used in official Tor Browser releases can be found in the +# tor-browser-build repo: +# https://gitweb.torproject.org/builders/tor-browser-build.git/ +# under: +# tor-browser-build/projects/firefox/mozconfig-$OS-$ARCH + +mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-@CONFIG_GUESS@ +mk_add_options MOZ_APP_DISPLAYNAME="Tor Browser" +export MOZILLA_OFFICIAL=1 + +ac_add_options --enable-optimize +ac_add_options --enable-rust-simd +ac_add_options --enable-official-branding + +# Let's support GTK3 for ESR60 +ac_add_options --enable-default-toolkit=cairo-gtk3 + +ac_add_options --disable-strip +ac_add_options --disable-install-strip +ac_add_options --disable-tests +ac_add_options --disable-debug +ac_add_options --disable-crashreporter +ac_add_options --disable-webrtc +ac_add_options --disable-parental-controls +# Let's make sure no preference is enabling either Adobe's or Google's CDM. +ac_add_options --disable-eme +ac_add_options --enable-proxy-bypass-protection + +# Disable telemetry +ac_add_options MOZ_TELEMETRY_REPORTING= + +ac_add_options --disable-tor-launcher +ac_add_options --with-tor-browser-version=dev-build +ac_add_options --disable-tor-browser-update diff --git a/.mozconfig-android b/.mozconfig-android new file mode 100755 index 000000000000..50015ec615ef --- /dev/null +++ b/.mozconfig-android @@ -0,0 +1,36 @@ +mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-arm-linux-androideabi +mk_add_options MOZ_APP_DISPLAYNAME="Tor Browser" +export MOZILLA_OFFICIAL=1 + +ac_add_options --enable-optimize +ac_add_options --enable-rust-simd +ac_add_options --enable-official-branding + +# Android +ac_add_options --enable-application=mobile/android +ac_add_options --target=arm-linux-androideabi +ac_add_options --with-android-ndk="$NDK_BASE" #Enter the android ndk location(ndk r17b) +ac_add_options --with-android-sdk="$SDK_BASE" #Enter the android sdk location +ac_add_options --with-branding=mobile/android/branding/alpha + +# Use Mozilla's Clang blobs +CC="$HOME/.mozbuild/clang/bin/clang" +CXX="$HOME/.mozbuild/clang/bin/clang++" + +#enable ccache to set amount of cache assigned for build. +ac_add_options --with-ccache + +ac_add_options --enable-strip +ac_add_options --disable-tests +ac_add_options --disable-debug +ac_add_options --disable-rust-debug + +ac_add_options --disable-updater +ac_add_options --disable-crashreporter +ac_add_options --disable-webrtc +ac_add_options --disable-parental-controls + +ac_add_options --enable-proxy-bypass-protection + +# Disable telemetry +ac_add_options MOZ_TELEMETRY_REPORTING= diff --git a/.mozconfig-asan b/.mozconfig-asan new file mode 100644 index 000000000000..bad7ea022c9f --- /dev/null +++ b/.mozconfig-asan @@ -0,0 +1,44 @@ +. $topsrcdir/browser/config/mozconfig + +export CFLAGS="-fsanitize=address -Dxmalloc=myxmalloc" +export CXXFLAGS="-fsanitize=address -Dxmalloc=myxmalloc" +# We need to add -ldl explicitely due to bug 1213698 +export LDFLAGS="-fsanitize=address -ldl" + +# Define HOST_CFLAGS, etc. to avoid compiling programs such as mbsdiff +# (which is part of mar-tools and is not distributed to end-users) with +# ASan. See bug 17858. +export HOST_CFLAGS="" +export HOST_CXXFLAGS="" +export HOST_LDFLAGS="-ldl" + +mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-@CONFIG_GUESS@ +mk_add_options MOZ_APP_DISPLAYNAME="Tor Browser" +export MOZILLA_OFFICIAL=1 +export BINDGEN_CFLAGS='--gcc-toolchain=/var/tmp/dist/gcc' + +ac_add_options --enable-address-sanitizer +ac_add_options --disable-jemalloc +ac_add_options --disable-elf-hack + +ac_add_options --enable-optimize +ac_add_options --enable-rust-simd +ac_add_options --enable-official-branding + +# Let's support GTK3 for ESR60 +ac_add_options --enable-default-toolkit=cairo-gtk3 + +ac_add_options --enable-tor-browser-update + +ac_add_options --disable-strip +ac_add_options --disable-install-strip +ac_add_options --enable-tests +ac_add_options --enable-debug +ac_add_options --disable-crashreporter +ac_add_options --disable-webrtc +ac_add_options --disable-parental-controls +ac_add_options --disable-eme +ac_add_options --enable-proxy-bypass-protection + +# Disable telemetry +ac_add_options MOZ_TELEMETRY_REPORTING= diff --git a/.mozconfig-mac b/.mozconfig-mac new file mode 100644 index 000000000000..26e2b6b92fdb --- /dev/null +++ b/.mozconfig-mac @@ -0,0 +1,56 @@ +# ld needs libLTO.so from llvm +mk_add_options "export LD_LIBRARY_PATH=$topsrcdir/clang/lib" + +CROSS_CCTOOLS_PATH=$topsrcdir/cctools +CROSS_SYSROOT=$topsrcdir/MacOSX10.7.sdk +CROSS_PRIVATE_FRAMEWORKS=$CROSS_SYSROOT/System/Library/PrivateFrameworks +HARDENING_FLAGS="-Werror=format -Werror=format-security -fstack-protector-strong -D_FORTIFY_SOURCE=2" +FLAGS="-target x86_64-apple-darwin10 -mlinker-version=136 -B $CROSS_CCTOOLS_PATH/bin -isysroot $CROSS_SYSROOT $HARDENING_FLAGS" + +export CC="$topsrcdir/clang/bin/clang $FLAGS" +export CXX="$topsrcdir/clang/bin/clang++ $FLAGS" +export CPP="$topsrcdir/clang/bin/clang $FLAGS -E" +export LLVMCONFIG=$topsrcdir/clang/bin/llvm-config +export LDFLAGS="-Wl,-syslibroot,$CROSS_SYSROOT -Wl,-dead_strip -Wl,-pie" +export TOOLCHAIN_PREFIX=$CROSS_CCTOOLS_PATH/bin/x86_64-apple-darwin10- +#TODO: bug 1184202 - would be nice if these could be detected with TOOLCHAIN_PREFIX automatically +export AR=${TOOLCHAIN_PREFIX}ar +export RANLIB=${TOOLCHAIN_PREFIX}ranlib +export STRIP=${TOOLCHAIN_PREFIX}strip +export OTOOL=${TOOLCHAIN_PREFIX}otool +export DSYMUTIL=$topsrcdir/clang/bin/llvm-dsymutil + +export HOST_CC="$topsrcdir/clang/bin/clang" +export HOST_CXX="$topsrcdir/clang/bin/clang++" +export HOST_CPP="$topsrcdir/clang/bin/clang -E" +export HOST_CFLAGS="-g" +export HOST_CXXFLAGS="-g" +export HOST_LDFLAGS="-g" + +ac_add_options --target=x86_64-apple-darwin +ac_add_options --with-macos-private-frameworks=$CROSS_PRIVATE_FRAMEWORKS + +mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-macos +mk_add_options MOZ_APP_DISPLAYNAME="Tor Browser" +export MOZILLA_OFFICIAL=1 + +ac_add_options --enable-application=browser +ac_add_options --enable-strip +ac_add_options --enable-official-branding +ac_add_options --enable-optimize +ac_add_options --enable-rust-simd +ac_add_options --disable-debug + +ac_add_options --enable-tor-browser-data-outside-app-dir +ac_add_options --enable-tor-browser-update + +ac_add_options --disable-crashreporter +ac_add_options --disable-webrtc +ac_add_options --disable-parental-controls +ac_add_options --disable-tests +# Let's make sure no preference is enabling either Adobe's or Google's CDM. +ac_add_options --disable-eme +ac_add_options --enable-proxy-bypass-protection + +# Disable telemetry +ac_add_options MOZ_TELEMETRY_REPORTING= diff --git a/.mozconfig-mingw b/.mozconfig-mingw new file mode 100644 index 000000000000..3ec6ff18a3e9 --- /dev/null +++ b/.mozconfig-mingw @@ -0,0 +1,31 @@ +CROSS_COMPILE=1 + +ac_add_options --enable-application=browser +ac_add_options --target=i686-w64-mingw32 +ac_add_options --with-toolchain-prefix=i686-w64-mingw32- +ac_add_options --enable-default-toolkit=cairo-windows +mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-mingw +mk_add_options MOZ_APP_DISPLAYNAME="Tor Browser" +export MOZILLA_OFFICIAL=1 + +ac_add_options --disable-debug +ac_add_options --enable-optimize +ac_add_options --enable-rust-simd +ac_add_options --enable-strip +ac_add_options --enable-official-branding + +ac_add_options --enable-tor-browser-update +ac_add_options --disable-bits-download + +# Let's make sure no preference is enabling either Adobe's or Google's CDM. +ac_add_options --disable-eme +ac_add_options --disable-crashreporter +ac_add_options --disable-maintenance-service +ac_add_options --disable-webrtc +ac_add_options --disable-parental-controls +ac_add_options --disable-tests +ac_add_options --enable-proxy-bypass-protection + +# Disable telemetry +ac_add_options MOZ_TELEMETRY_REPORTING= +ac_add_options --disable-default-browser-agent diff --git a/browser/base/moz.build b/browser/base/moz.build index 4f62ec18721c..17dcd86ff4b2 100644 --- a/browser/base/moz.build +++ b/browser/base/moz.build @@ -78,6 +78,9 @@ if CONFIG["MOZ_WIDGET_TOOLKIT"] in ("windows", "gtk", "cocoa"): if CONFIG["MOZ_WIDGET_TOOLKIT"] in ("windows", "gtk"): DEFINES["MENUBAR_CAN_AUTOHIDE"] = 1 +if CONFIG["TOR_BROWSER_UPDATE"]: + DEFINES["TOR_BROWSER_UPDATE"] = 1 + JAR_MANIFESTS += ["jar.mn"] GeneratedFile( diff --git a/browser/installer/Makefile.in b/browser/installer/Makefile.in index ad725c5114b0..4fa715669e8b 100644 --- a/browser/installer/Makefile.in +++ b/browser/installer/Makefile.in @@ -82,6 +82,14 @@ endif endif endif +ifdef TOR_BROWSER_DISABLE_TOR_LAUNCHER +DEFINES += -DTOR_BROWSER_DISABLE_TOR_LAUNCHER +endif + +ifdef TOR_BROWSER_UPDATE +DEFINES += -DTOR_BROWSER_UPDATE +endif + ifneq (,$(filter WINNT Darwin Android,$(OS_TARGET))) DEFINES += -DMOZ_SHARED_MOZGLUE=1 endif diff --git a/browser/moz.configure b/browser/moz.configure index 8653bcbb165d..5a0b722b915e 100644 --- a/browser/moz.configure +++ b/browser/moz.configure @@ -5,11 +5,11 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. imply_option("MOZ_PLACES", True) -imply_option("MOZ_SERVICES_HEALTHREPORT", True) +imply_option("MOZ_SERVICES_HEALTHREPORT", False) imply_option("MOZ_SERVICES_SYNC", True) -imply_option("MOZ_DEDICATED_PROFILES", True) -imply_option("MOZ_BLOCK_PROFILE_DOWNGRADE", True) -imply_option("MOZ_NORMANDY", True) +imply_option("MOZ_DEDICATED_PROFILES", False) +imply_option("MOZ_BLOCK_PROFILE_DOWNGRADE", False) +imply_option("MOZ_NORMANDY", False) with only_when(target_is_linux & compile_environment): option(env="MOZ_NO_PIE_COMPAT", help="Enable non-PIE wrapper") diff --git a/build/moz.configure/android-sdk.configure b/build/moz.configure/android-sdk.configure index fac3881ecb1b..8c36e5306c20 100644 --- a/build/moz.configure/android-sdk.configure +++ b/build/moz.configure/android-sdk.configure @@ -48,7 +48,7 @@ def android_sdk_root(value): @dependable def android_sdk_version(): - return namespace(build_tools_version="29.0.3", target_sdk_version="29") + return namespace(build_tools_version="29.0.2", target_sdk_version="29") @depends(android_sdk_root, android_sdk_version) diff --git a/build/moz.configure/old.configure b/build/moz.configure/old.configure index 35ab75df3a14..95f4200d0973 100644 --- a/build/moz.configure/old.configure +++ b/build/moz.configure/old.configure @@ -119,6 +119,11 @@ def old_configure_options(*options): "--with-user-appdir", "--x-includes", "--x-libraries", + # Tor additions. + "--with-tor-browser-version", + "--enable-tor-browser-update", + "--enable-tor-browser-data-outside-app-dir", + "--enable-tor-launcher", ) def prepare_configure_options(host, target, all_options, *options): # old-configure only supports the options listed in @old_configure_options diff --git a/mobile/android/confvars.sh b/mobile/android/confvars.sh index 70e13c85b258..b2670451ed91 100644 --- a/mobile/android/confvars.sh +++ b/mobile/android/confvars.sh @@ -29,6 +29,15 @@ MOZ_ANDROID_BROWSER_INTENT_CLASS=org.mozilla.gecko.BrowserApp MOZ_NO_SMART_CARDS=1 +# Adds MIME-type support for raw video MOZ_RAW=1 MOZ_APP_ID={aa3c5121-dab2-40e2-81ca-7ea25febc110} + +### Tor Browser for Android ### + +# Disable telemetry at compile-time +unset MOZ_TELEMETRY_REPORTING + +# Disable data reporting at compile-time +unset MOZ_DATA_REPORTING diff --git a/mobile/android/geckoview/build.gradle b/mobile/android/geckoview/build.gradle index 28841eb020d6..e50671c35dc4 100644 --- a/mobile/android/geckoview/build.gradle +++ b/mobile/android/geckoview/build.gradle @@ -93,6 +93,7 @@ android { buildConfigField 'String', "MOZ_APP_DISPLAYNAME", "\"${mozconfig.substs.MOZ_APP_DISPLAYNAME}\""; buildConfigField 'String', "MOZ_APP_UA_NAME", "\"${mozconfig.substs.MOZ_APP_UA_NAME}\""; buildConfigField 'String', "MOZ_UPDATE_CHANNEL", "\"${mozconfig.substs.MOZ_UPDATE_CHANNEL}\""; + buildConfigField 'String', "TOR_BROWSER_VERSION", "\"${mozconfig.substs.TOR_BROWSER_VERSION}\""; // MOZILLA_VERSION is oddly quoted from autoconf, but we don't have to handle it specially in Gradle. buildConfigField 'String', "MOZILLA_VERSION", "\"${mozconfig.substs.MOZILLA_VERSION}\""; diff --git a/mobile/android/moz.configure b/mobile/android/moz.configure index a1d3f4e65c48..70822bdfcafd 100644 --- a/mobile/android/moz.configure +++ b/mobile/android/moz.configure @@ -13,7 +13,7 @@ project_flag( project_flag( "MOZ_ANDROID_HLS_SUPPORT", help="Enable HLS (HTTP Live Streaming) support (currently using the ExoPlayer library)", - default=True, + default=False, ) option( @@ -62,10 +62,14 @@ def fennec_nightly(nightly): imply_option("MOZ_NORMANDY", False) -imply_option("MOZ_SERVICES_HEALTHREPORT", True) imply_option("MOZ_ANDROID_HISTORY", True) imply_option("--enable-small-chunk-size", True) +# Comment this so we can imply |False| in torbrowser.configure +# The Build system doesn't allow multiple imply_option() +# calls with the same key. +# imply_option("MOZ_SERVICES_HEALTHREPORT", True) + @depends(target) def check_target(target): @@ -81,6 +85,8 @@ def check_target(target): ) +include("torbrowser.configure") + include("../../toolkit/moz.configure") include("../../build/moz.configure/android-sdk.configure") include("../../build/moz.configure/java.configure") @@ -98,3 +104,15 @@ set_config( "MOZ_ANDROID_FAT_AAR_ARCHITECTURES", depends("MOZ_ANDROID_FAT_AAR_ARCHITECTURES")(lambda x: x), ) + +project_flag( + "MOZ_ANDROID_NETWORK_STATE", + help="Include permission for accessing WiFi/network state on Android", + default=False, +) + +project_flag( + "MOZ_ANDROID_LOCATION", + help="Include permission for accessing fine and course-grain Location on Android", + default=False, +) diff --git a/mobile/android/torbrowser.configure b/mobile/android/torbrowser.configure new file mode 100644 index 000000000000..bcb725cae121 --- /dev/null +++ b/mobile/android/torbrowser.configure @@ -0,0 +1,30 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Set Tor Browser default config + +imply_option("MOZ_ANDROID_EXCLUDE_FONTS", False) + +# Disable uploading crash reports and dump files to an external server +# This is still configured in old-configure. Uncomment when this moves +# to the python config +# imply_option("MOZ_CRASHREPORTER", False) + +# Disable uploading information about the browser configuration and +# performance to an external server +imply_option("MOZ_SERVICES_HEALTHREPORT", False) + +# Disable creating telemetry and data reports that are uploaded to an +# external server +# These aren't actually configure options. These are disabled in +# confvars.sh, but they look like configure options so we'll document +# them here, as well. +# XXX: no confvars.sh here +# imply_option("MOZ_TELEMETRY_REPORTING", False) +# imply_option("MOZ_DATA_REPORTING", False) + +imply_option("MOZ_ANDROID_NETWORK_STATE", False) +imply_option("MOZ_ANDROID_LOCATION", False) diff --git a/old-configure.in b/old-configure.in index 0ac86af0c8c7..f3ed00e15d1e 100644 --- a/old-configure.in +++ b/old-configure.in @@ -1892,6 +1892,55 @@ if test -n "$MOZ_UPDATER"; then AC_DEFINE(MOZ_UPDATER) fi +dnl ======================================================== +dnl Tor additions +dnl ======================================================== +MOZ_ARG_WITH_STRING(tor-browser-version, +[ --with-tor-browser-version=VERSION + Set Tor Browser version, e.g., 7.0a1], + TOR_BROWSER_VERSION="$withval") + +if test -z "$TOR_BROWSER_VERSION"; then + AC_MSG_ERROR([--with-tor-browser-version is required for Tor Browser.]) +fi + +MOZ_ARG_ENABLE_BOOL(tor-browser-update, +[ --enable-tor-browser-update + Enable Tor Browser update], + TOR_BROWSER_UPDATE=1, + TOR_BROWSER_UPDATE= ) + +if test -n "$TOR_BROWSER_UPDATE"; then + AC_DEFINE(TOR_BROWSER_UPDATE) +fi + +MOZ_ARG_ENABLE_BOOL(tor-browser-data-outside-app-dir, +[ --enable-tor-browser-data-outside-app-dir + Enable Tor Browser data outside of app directory], + TOR_BROWSER_DATA_OUTSIDE_APP_DIR=1, + TOR_BROWSER_DATA_OUTSIDE_APP_DIR= ) + +if test -n "$TOR_BROWSER_DATA_OUTSIDE_APP_DIR"; then + AC_DEFINE(TOR_BROWSER_DATA_OUTSIDE_APP_DIR) +fi + +AC_DEFINE_UNQUOTED(TOR_BROWSER_VERSION,$TOR_BROWSER_VERSION) +AC_DEFINE_UNQUOTED(TOR_BROWSER_VERSION_QUOTED,"$TOR_BROWSER_VERSION") +AC_SUBST(TOR_BROWSER_UPDATE) +AC_SUBST(TOR_BROWSER_DATA_OUTSIDE_APP_DIR) + +MOZ_ARG_DISABLE_BOOL(tor-launcher, +[ --disable-tor-launcher + Do not include Tor Launcher], + TOR_BROWSER_DISABLE_TOR_LAUNCHER=1, + TOR_BROWSER_DISABLE_TOR_LAUNCHER=) + +if test -n "$TOR_BROWSER_DISABLE_TOR_LAUNCHER"; then + AC_DEFINE(TOR_BROWSER_DISABLE_TOR_LAUNCHER) +fi + +AC_SUBST(TOR_BROWSER_DISABLE_TOR_LAUNCHER) + dnl ======================================================== dnl parental controls (for Windows Vista) dnl ======================================================== diff --git a/security/moz.build b/security/moz.build index 18e50f9dcc37..8d0427525487 100644 --- a/security/moz.build +++ b/security/moz.build @@ -85,7 +85,7 @@ gyp_vars["nss_dist_obj_dir"] = "$PRODUCT_DIR/dist/bin" gyp_vars["disable_tests"] = 1 gyp_vars["disable_dbm"] = 1 gyp_vars["disable_libpkix"] = 1 -gyp_vars["enable_sslkeylogfile"] = 1 +gyp_vars["enable_sslkeylogfile"] = 0 # pkg-config won't reliably find zlib on our builders, so just force it. # System zlib is only used for modutil and signtool unless # SSL zlib is enabled, which we are disabling immediately below this. diff --git a/security/nss/lib/ssl/Makefile b/security/nss/lib/ssl/Makefile index 8a8b06f4b508..90571bb3e256 100644 --- a/security/nss/lib/ssl/Makefile +++ b/security/nss/lib/ssl/Makefile @@ -41,7 +41,7 @@ endif # Enable key logging by default in debug builds, but not opt builds. # Logging still needs to be enabled at runtime through env vars. -NSS_ALLOW_SSLKEYLOGFILE ?= $(if $(BUILD_OPT),0,1) +NSS_ALLOW_SSLKEYLOGFILE ?= 0 ifeq (1,$(NSS_ALLOW_SSLKEYLOGFILE)) DEFINES += -DNSS_ALLOW_SSLKEYLOGFILE=1 endif diff --git a/toolkit/modules/AppConstants.jsm b/toolkit/modules/AppConstants.jsm index 004edddcffd6..dc71230b77fb 100644 --- a/toolkit/modules/AppConstants.jsm +++ b/toolkit/modules/AppConstants.jsm @@ -342,6 +342,14 @@ this.AppConstants = Object.freeze({ MOZ_WIDGET_TOOLKIT: "@MOZ_WIDGET_TOOLKIT@", ANDROID_PACKAGE_NAME: "@ANDROID_PACKAGE_NAME@", + TOR_BROWSER_VERSION: "@TOR_BROWSER_VERSION@", + TOR_BROWSER_DATA_OUTSIDE_APP_DIR: +#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR + true, +#else + false, +#endif + DEBUG_JS_MODULES: "@DEBUG_JS_MODULES@", MOZ_BING_API_CLIENTID: "@MOZ_BING_API_CLIENTID@", @@ -426,4 +434,11 @@ this.AppConstants = Object.freeze({ #else false, #endif + + TOR_BROWSER_UPDATE: +#ifdef TOR_BROWSER_UPDATE + true, +#else + false, +#endif }); diff --git a/toolkit/modules/moz.build b/toolkit/modules/moz.build index 88676f6f303f..cd4a66093c53 100644 --- a/toolkit/modules/moz.build +++ b/toolkit/modules/moz.build @@ -305,6 +305,9 @@ for var in ( if CONFIG[var]: DEFINES[var] = True +if CONFIG["TOR_BROWSER_UPDATE"]: + DEFINES["TOR_BROWSER_UPDATE"] = 1 + JAR_MANIFESTS += ["jar.mn"] DEFINES["TOPOBJDIR"] = TOPOBJDIR
1 0
0 0
[tor-browser/tor-browser-87.0b4-10.5-1] Bug 12620: TorBrowser regression tests
by sysrqb@torproject.org 11 Mar '21

11 Mar '21
commit 017d2f328fe9c013449874b186185938420f98da Author: Arthur Edelstein <arthuredelstein(a)gmail.com> Date: Wed Aug 27 16:25:00 2014 -0700 Bug 12620: TorBrowser regression tests Regression tests for Bug #2950: Make Permissions Manager memory-only Regression tests for TB4: Tor Browser's Firefox preference overrides. Note: many more functional tests could be made here Regression tests for #2874: Block Components.interfaces from content Bug 18923: Add a script to run all Tor Browser specific tests Regression tests for Bug #16441: Suppress "Reset Tor Browser" prompt. --- run-tbb-tests | 66 +++++++++++++++++++++++++++++++++++ tbb-tests-ignore.txt | 13 +++++++ tbb-tests/browser.ini | 5 +++ tbb-tests/browser_tor_TB4.js | 35 +++++++++++++++++++ tbb-tests/browser_tor_bug2950.js | 74 ++++++++++++++++++++++++++++++++++++++++ tbb-tests/mochitest.ini | 3 ++ tbb-tests/moz.build | 9 +++++ tbb-tests/test_tor_bug2874.html | 25 ++++++++++++++ toolkit/toolkit.mozbuild | 3 +- 9 files changed, 232 insertions(+), 1 deletion(-) diff --git a/run-tbb-tests b/run-tbb-tests new file mode 100755 index 000000000000..bc09839f9f05 --- /dev/null +++ b/run-tbb-tests @@ -0,0 +1,66 @@ +#!/bin/bash + +# This script runs all the Mochitest tests that have been added or +# modified since the last ffxbld commit. +# +# It does not currently run XPCShell tests. We should change this if we +# start using this type or other types of tests. +# +# The logs of the tests are stored in the tbb-tests.log file. +# Ignored tests are listed in the tbb-tests-ignore.txt file. +# +# https://trac.torproject.org/projects/tor/ticket/18923 + +IFS=$'\n' + +if [ -n "$USE_TESTS_LIST" ] && [ -f tbb-tests-list.txt ] +then + echo "Using tests list from file tbb-tests-list.txt" + tests=($(cat tbb-tests-list.txt)) +else + ffxbld_commit=$(git log -500 --format='oneline' | grep "TB3: Tor Browser's official .mozconfigs." \ + | head -1 | cut -d ' ' -f 1) + + tests=($(git diff --name-status "$ffxbld_commit" HEAD | \ + grep -e '^[AM].*/test_[^/]\+\.\(html\|xul\)$' \ + -e '^[AM].*/browser_[^/]\+\.js$' \ + | sed 's/^[AM]\s\+//')) +fi + +echo 'The following tests will be run:' +for i in "${!tests[@]}" +do + if [ -z "$USE_TESTS_LIST" ] \ + && grep -q "^${tests[$i]}$" tbb-tests-ignore.txt + then + unset "tests[$i]" + continue + fi + echo "- ${tests[$i]}" +done + +if [ -n "$WRITE_TESTS_LIST" ] +then + rm -f tbb-tests-list.txt + for i in "${!tests[@]}" + do + echo "${tests[$i]}" >> tbb-tests-list.txt + done + exit 0 +fi + +rm -f tbb-tests.log +echo $'\n''Starting tests' +# We need `security.nocertdb = false` because of #18087. That pref is +# forced to have the same value as `browser.privatebrowsing.autostart` in +# torbutton, so we just set `browser.privatebrowsing.autostart=false` here. +./mach mochitest --log-tbpl tbb-tests.log \ + --setpref network.file.path_blacklist='' \ + --setpref extensions.torbutton.use_nontor_proxy=true \ + --setpref browser.privatebrowsing.autostart=false \ + "${tests[@]}" + +echo "*************************" +echo "*************************" +echo "Summary of failed tests:" +grep --color=never TEST-UNEXPECTED-FAIL tbb-tests.log diff --git a/tbb-tests-ignore.txt b/tbb-tests-ignore.txt new file mode 100644 index 000000000000..ee3927a9e7c4 --- /dev/null +++ b/tbb-tests-ignore.txt @@ -0,0 +1,13 @@ +browser/extensions/onboarding/test/browser/browser_onboarding_accessibility.js +browser/extensions/onboarding/test/browser/browser_onboarding_keyboard.js +browser/extensions/onboarding/test/browser/browser_onboarding_notification.js +browser/extensions/onboarding/test/browser/browser_onboarding_notification_2.js +browser/extensions/onboarding/test/browser/browser_onboarding_notification_3.js +browser/extensions/onboarding/test/browser/browser_onboarding_notification_4.js +browser/extensions/onboarding/test/browser/browser_onboarding_notification_5.js +browser/extensions/onboarding/test/browser/browser_onboarding_notification_click_auto_complete_tour.js +browser/extensions/onboarding/test/browser/browser_onboarding_select_default_tour.js +browser/extensions/onboarding/test/browser/browser_onboarding_skip_tour.js +browser/extensions/onboarding/test/browser/browser_onboarding_tours.js +browser/extensions/onboarding/test/browser/browser_onboarding_tourset.js +browser/extensions/onboarding/test/browser/browser_onboarding_uitour.js diff --git a/tbb-tests/browser.ini b/tbb-tests/browser.ini new file mode 100644 index 000000000000..f481660f1417 --- /dev/null +++ b/tbb-tests/browser.ini @@ -0,0 +1,5 @@ +[DEFAULT] + +[browser_tor_bug2950.js] +[browser_tor_omnibox.js] +[browser_tor_TB4.js] diff --git a/tbb-tests/browser_tor_TB4.js b/tbb-tests/browser_tor_TB4.js new file mode 100644 index 000000000000..8bb12f360e5e --- /dev/null +++ b/tbb-tests/browser_tor_TB4.js @@ -0,0 +1,35 @@ +// # Test for TB4: Tor Browser's Firefox preference overrides +// This is a minimal test to check whether the 000-tor-browser.js +// pref overrides are being used at all or not. More comprehensive +// pref tests are maintained in the tor-browser-bundle-testsuite project. + +function test() { + +let expectedPrefs = [ + // Homepage + ["browser.startup.homepage", "about:tor"], + + // Disable the "Refresh" prompt that is displayed for stale profiles. + ["browser.disableResetPrompt", true], + + // Version placeholder + ["torbrowser.version", "dev-build"], + ]; + +let getPref = function (prefName) { + let type = Services.prefs.getPrefType(prefName); + if (type === Services.prefs.PREF_INT) return Services.prefs.getIntPref(prefName); + if (type === Services.prefs.PREF_BOOL) return Services.prefs.getBoolPref(prefName); + if (type === Services.prefs.PREF_STRING) return Services.prefs.getCharPref(prefName); + // Something went wrong. + throw new Error("Can't access pref " + prefName); +}; + +let testPref = function([key, expectedValue]) { + let foundValue = getPref(key); + is(foundValue, expectedValue, "Pref '" + key + "' should be '" + expectedValue +"'."); +}; + +expectedPrefs.map(testPref); + +} // end function test() diff --git a/tbb-tests/browser_tor_bug2950.js b/tbb-tests/browser_tor_bug2950.js new file mode 100644 index 000000000000..16e41344a3c4 --- /dev/null +++ b/tbb-tests/browser_tor_bug2950.js @@ -0,0 +1,74 @@ +// # Regression tests for tor Bug #2950, Make Permissions Manager memory-only +// Ensures that permissions.sqlite file in profile directory is not written to, +// even when we write a value to Firefox's permissions database. + +// The requisite test() function. +function test() { + +// Needed because of asynchronous part later in the test. +waitForExplicitFinish(); + +// Shortcut +let Ci = Components.interfaces; + +// ## utility functions + +// __principal(spec)__. +// Creates a principal instance from a spec +// (string address such as "https://www.torproject.org"). +let principal = spec => Services.scriptSecurityManager.createContentPrincipalFromOrigin(spec); + +// __setPermission(spec, key, value)__. +// Sets the site permission of type key to value, for the site located at address spec. +let setPermission = (spec, key, value) => SitePermissions.setForPrincipal(principal(spec), key, value); + +// __getPermission(spec, key)__. +// Reads the site permission value for permission type key, for the site +// located at address spec. +let getPermission = (spec, key) => SitePermissions.getForPrincipal(principal(spec), key); + +// __profileDirPath__. +// The Firefox Profile directory. Expected location of various persistent files. +let profileDirPath = Services.dirsvc.get("ProfD", Components.interfaces.nsIFile).path; + +// __fileInProfile(fileName)__. +// Returns an nsIFile instance corresponding to a file in the Profile directory. +let fileInProfile = fileName => FileUtils.File(profileDirPath + "/" + fileName); + +// ## Now let's run the test. + +let SITE = "https://www.torproject.org", + KEY = "popup"; + +let permissionsFile = fileInProfile("permissions.sqlite"), + lastModifiedTime = null, + newModifiedTime = null; +if (permissionsFile.exists()) { + lastModifiedTime = permissionsFile.lastModifiedTime; +} +// Read the original value of the permission. +let originalValue = getPermission(SITE, KEY); + +// We need to delay by at least 1000 ms, because that's the granularity +// of file time stamps, it seems. +window.setTimeout( + function () { + // Set the permission to a new value. + setPermission(SITE, KEY, SitePermissions.BLOCK); + // Now read back the permission value again. + let newReadValue = getPermission(SITE, KEY); + // Compare to confirm that the permission + // value was successfully changed. + Assert.notDeepEqual(originalValue, newReadValue, "Set a value in permissions db (perhaps in memory)."); + // If file existed or now exists, get the current time stamp. + if (permissionsFile.exists()) { + newModifiedTime = permissionsFile.lastModifiedTime; + } + // If file was created or modified since we began this test, + // then permissions db is not memory only. Complain! + is(lastModifiedTime, newModifiedTime, "Don't write to permissions.sqlite file on disk."); + // We are done with the test. + finish(); + }, 1100); + +} // test() diff --git a/tbb-tests/mochitest.ini b/tbb-tests/mochitest.ini new file mode 100644 index 000000000000..cc5172733bbe --- /dev/null +++ b/tbb-tests/mochitest.ini @@ -0,0 +1,3 @@ +[DEFAULT] + +[test_tor_bug2874.html] diff --git a/tbb-tests/moz.build b/tbb-tests/moz.build new file mode 100644 index 000000000000..01db60b9c28a --- /dev/null +++ b/tbb-tests/moz.build @@ -0,0 +1,9 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +MOCHITEST_MANIFESTS += ["mochitest.ini"] + +BROWSER_CHROME_MANIFESTS += ["browser.ini"] diff --git a/tbb-tests/test_tor_bug2874.html b/tbb-tests/test_tor_bug2874.html new file mode 100644 index 000000000000..c0a956e9f687 --- /dev/null +++ b/tbb-tests/test_tor_bug2874.html @@ -0,0 +1,25 @@ +<!DOCTYPE HTML> +<html> +<!-- +Tor bug +https://trac.torproject.org/projects/tor/ticket/2874 +--> +<head> + <meta charset="utf-8"> + <title>Test for Tor Bug 2874</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + is(typeof Components, 'undefined', "The global window object should not expose a Components property to untrusted content."); + </script> +</head> +<body> +<a target="_blank" href="https://trac.torproject.org/projects/tor/ticket/2874">Tor Bug 2874</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/toolkit/toolkit.mozbuild b/toolkit/toolkit.mozbuild index bbc3c98e4885..f77d8a3f59ed 100644 --- a/toolkit/toolkit.mozbuild +++ b/toolkit/toolkit.mozbuild @@ -96,7 +96,8 @@ if CONFIG['MOZ_WEBRTC'] and CONFIG['COMPILE_ENVIRONMENT']: ] if CONFIG['ENABLE_TESTS']: - DIRS += ['/testing/specialpowers'] + DIRS += ['/testing/specialpowers', + '/tbb-tests'] DIRS += [ '/testing/gtest',
1 0
0 0
[tor-browser/tor-browser-87.0b4-10.5-1] Bug 28044: Integrate Tor Launcher into tor-browser
by sysrqb@torproject.org 11 Mar '21

11 Mar '21
commit 139d70e87f421a44fe017c09fd9f2119fcc78f8d Author: Kathy Brade <brade(a)pearlcrescent.com> Date: Tue Feb 26 10:07:17 2019 -0500 Bug 28044: Integrate Tor Launcher into tor-browser Build and package Tor Launcher as part of the browser (similar to how pdfjs is handled). If a Tor Launcher extension is present in the user's profile, it is removed. --- browser/extensions/moz.build | 3 +++ browser/installer/package-manifest.in | 5 +++++ toolkit/mozapps/extensions/internal/XPIProvider.jsm | 10 ++++++++++ 3 files changed, 18 insertions(+) diff --git a/browser/extensions/moz.build b/browser/extensions/moz.build index 0eb3c53e76c2..df98fa94f629 100644 --- a/browser/extensions/moz.build +++ b/browser/extensions/moz.build @@ -5,3 +5,6 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. DIRS += ["doh-rollout", "formautofill", "screenshots", "webcompat", "report-site-issue"] + +if not CONFIG["TOR_BROWSER_DISABLE_TOR_LAUNCHER"]: + DIRS += ["tor-launcher"] diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index a5148a03f0a6..30b88fc38277 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -255,6 +255,11 @@ @RESPATH@/browser/chrome/browser.manifest @RESPATH@/chrome/pdfjs.manifest @RESPATH@/chrome/pdfjs/* +#ifndef TOR_BROWSER_DISABLE_TOR_LAUNCHER +@RESPATH@/browser/chrome/torlauncher.manifest +@RESPATH@/browser/chrome/torlauncher/* +@RESPATH@/browser/@PREF_DIR@/torlauncher-prefs.js +#endif @RESPATH@/chrome/toolkit@JAREXT@ @RESPATH@/chrome/toolkit.manifest @RESPATH@/chrome/recording.manifest diff --git a/toolkit/mozapps/extensions/internal/XPIProvider.jsm b/toolkit/mozapps/extensions/internal/XPIProvider.jsm index ac5bdacb6de9..d1ed386fe676 100644 --- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm +++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm @@ -1469,6 +1469,16 @@ var XPIStates = { for (let [id, file] of loc.readAddons()) { knownIds.delete(id); + // Since it is now part of the browser, uninstall the Tor Launcher + // extension. This will remove the Tor Launcher .xpi from user + // profiles on macOS. + if (id === "tor-launcher(a)torproject.org") { + logger.debug("Uninstalling the Tor Launcher extension."); + loc.installer.uninstallAddon(id); + changed = true; + continue; + } + let xpiState = loc.get(id); if (!xpiState) { // If the location is not supported for sideloading, skip new
1 0
0 0
[tor-browser/tor-browser-87.0b4-10.5-1] Bug 40069: Add helpers for message passing with extensions
by sysrqb@torproject.org 11 Mar '21

11 Mar '21
commit a822d5e1342ddc7a6f15ede5b079fd833b8bb14f Author: Alex Catarineu <acat(a)torproject.org> Date: Sun Aug 2 19:12:25 2020 +0200 Bug 40069: Add helpers for message passing with extensions --- toolkit/components/extensions/ExtensionParent.jsm | 47 +++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/toolkit/components/extensions/ExtensionParent.jsm b/toolkit/components/extensions/ExtensionParent.jsm index de02fdb81f4a..8f20965fa74a 100644 --- a/toolkit/components/extensions/ExtensionParent.jsm +++ b/toolkit/components/extensions/ExtensionParent.jsm @@ -264,6 +264,8 @@ const ProxyMessenger = { /** @type Map<number, ParentPort> */ ports: new Map(), + _torRuntimeMessageListeners: [], + init() { this.conduit = new BroadcastConduit(ProxyMessenger, { id: "ProxyMessenger", @@ -326,6 +328,10 @@ const ProxyMessenger = { }, async recvRuntimeMessage(arg, { sender }) { + // We need to listen to some extension messages in Tor Browser + for (const listener of this._torRuntimeMessageListeners) { + listener(arg); + } arg.firstResponse = true; let kind = await this.normalizeArgs(arg, sender); let result = await this.conduit.castRuntimeMessage(kind, arg); @@ -1878,6 +1884,45 @@ for (let name of StartupCache.STORE_NAMES) { StartupCache[name] = new CacheStore(name); } +async function torSendExtensionMessage(extensionId, message) { + // This should broadcast the message to all children "conduits" + // listening for a "RuntimeMessage". Those children conduits + // will either be extension background pages or other extension + // pages listening to browser.runtime.onMessage. + const result = await ProxyMessenger.conduit.castRuntimeMessage("messenger", { + extensionId, + holder: new StructuredCloneHolder(message), + firstResponse: true, + sender: { + id: extensionId, + envType: "addon_child", + }, + }); + return result + ? result.value + : Promise.reject({ message: ERROR_NO_RECEIVERS }); +} + +async function torWaitForExtensionMessage(extensionId, checker) { + return new Promise(resolve => { + const msgListener = msg => { + try { + if (msg && msg.extensionId === extensionId) { + const deserialized = msg.holder.deserialize({}); + if (checker(deserialized)) { + const idx = ProxyMessenger._torRuntimeMessageListeners.indexOf( + msgListener + ); + ProxyMessenger._torRuntimeMessageListeners.splice(idx, 1); + resolve(deserialized); + } + } + } catch (e) {} + }; + ProxyMessenger._torRuntimeMessageListeners.push(msgListener); + }); +} + var ExtensionParent = { GlobalManager, HiddenExtensionPage, @@ -1889,6 +1934,8 @@ var ExtensionParent = { promiseExtensionViewLoaded, watchExtensionProxyContextLoad, DebugUtils, + torSendExtensionMessage, + torWaitForExtensionMessage, }; // browserPaintedPromise and browserStartupPromise are promises that
1 0
0 0
[tor-browser/tor-browser-87.0b4-10.5-1] Add TorStrings module for localization
by sysrqb@torproject.org 11 Mar '21

11 Mar '21
commit 057ac537a3dc9eb11e630b6567a02d5e506eb103 Author: Alex Catarineu <acat(a)torproject.org> Date: Fri Jul 24 21:15:20 2020 +0200 Add TorStrings module for localization --- browser/modules/TorStrings.jsm | 490 +++++++++++++++++++++++++++++++++++++++++ browser/modules/moz.build | 1 + 2 files changed, 491 insertions(+) diff --git a/browser/modules/TorStrings.jsm b/browser/modules/TorStrings.jsm new file mode 100644 index 000000000000..e8a8d37ae373 --- /dev/null +++ b/browser/modules/TorStrings.jsm @@ -0,0 +1,490 @@ +"use strict"; + +var EXPORTED_SYMBOLS = ["TorStrings"]; + +const { XPCOMUtils } = ChromeUtils.import( + "resource://gre/modules/XPCOMUtils.jsm" +); +const { Services } = ChromeUtils.import( + "resource://gre/modules/Services.jsm" +); +const { getLocale } = ChromeUtils.import( + "resource://torbutton/modules/utils.js" +); + +XPCOMUtils.defineLazyGlobalGetters(this, ["DOMParser"]); +XPCOMUtils.defineLazyGetter(this, "domParser", () => { + const parser = new DOMParser(); + parser.forceEnableDTD(); + return parser; +}); + +/* + Tor DTD String Bundle + + DTD strings loaded from torbutton/tor-launcher, but provide a fallback in case they aren't available +*/ +class TorDTDStringBundle { + constructor(aBundleURLs, aPrefix) { + let locations = []; + for (const [index, url] of aBundleURLs.entries()) { + locations.push(`<!ENTITY % dtd_${index} SYSTEM "${url}">%dtd_${index};`); + } + this._locations = locations; + this._prefix = aPrefix; + } + + // copied from testing/marionette/l10n.js + localizeEntity(urls, id) { + // Use the DOM parser to resolve the entity and extract its real value + let header = `<?xml version="1.0"?><!DOCTYPE elem [${this._locations.join( + "" + )}]>`; + let elem = `<elem id="elementID">&${id};</elem>`; + let doc = domParser.parseFromString(header + elem, "text/xml"); + let element = doc.querySelector("elem[id='elementID']"); + + if (element === null) { + throw new Error(`Entity with id='${id}' hasn't been found`); + } + + return element.textContent; + } + + getString(key, fallback) { + if (key) { + try { + return this.localizeEntity(this._bundleURLs, `${this._prefix}${key}`); + } catch (e) {} + } + + // on failure, assign the fallback if it exists + if (fallback) { + return fallback; + } + // otherwise return string key + return `$(${key})`; + } +} + +/* + Tor Property String Bundle + + Property strings loaded from torbutton/tor-launcher, but provide a fallback in case they aren't available +*/ +class TorPropertyStringBundle { + constructor(aBundleURL, aPrefix) { + try { + this._bundle = Services.strings.createBundle(aBundleURL); + } catch (e) {} + + this._prefix = aPrefix; + } + + getString(key, fallback) { + if (key) { + try { + return this._bundle.GetStringFromName(`${this._prefix}${key}`); + } catch (e) {} + } + + // on failure, assign the fallback if it exists + if (fallback) { + return fallback; + } + // otherwise return string key + return `$(${key})`; + } +} + +/* + Security Level Strings +*/ +var TorStrings = { + /* + Tor Browser Security Level Strings + */ + securityLevel: (function() { + let tsb = new TorDTDStringBundle( + ["chrome://torbutton/locale/torbutton.dtd"], + "torbutton.prefs.sec_" + ); + let getString = function(key, fallback) { + return tsb.getString(key, fallback); + }; + + // read localized strings from torbutton; but use hard-coded en-US strings as fallbacks in case of error + let retval = { + securityLevel: getString("caption", "Security Level"), + customWarning: getString("custom_warning", "Custom"), + overview: getString( + "overview", + "Disable certain web features that can be used to attack your security and anonymity." + ), + standard: { + level: getString("standard_label", "Standard"), + tooltip: getString("standard_tooltip", "Security Level : Standard"), + summary: getString( + "standard_description", + "All Tor Browser and website features are enabled." + ), + }, + safer: { + level: getString("safer_label", "Safer"), + tooltip: getString("safer_tooltip", "Security Level : Safer"), + summary: getString( + "safer_description", + "Disables website features that are often dangerous, causing some sites to lose functionality." + ), + description1: getString( + "js_on_https_sites_only", + "JavaScript is disabled on non-HTTPS sites." + ), + description2: getString( + "limit_typography", + "Some fonts and math symbols are disabled." + ), + description3: getString( + "click_to_play_media", + "Audio and video (HTML5 media), and WebGL are click-to-play." + ), + }, + safest: { + level: getString("safest_label", "Safest"), + tooltip: getString("safest_tooltip", "Security Level : Safest"), + summary: getString( + "safest_description", + "Only allows website features required for static sites and basic services. These changes affect images, media, and scripts." + ), + description1: getString( + "js_disabled", + "JavaScript is disabled by default on all sites." + ), + description2: getString( + "limit_graphics_and_typography", + "Some fonts, icons, math symbols, and images are disabled." + ), + description3: getString( + "click_to_play_media", + "Audio and video (HTML5 media), and WebGL are click-to-play." + ), + }, + custom: { + summary: getString( + "custom_summary", + "Your custom browser preferences have resulted in unusual security settings. For security and privacy reasons, we recommend you choose one of the default security levels." + ), + }, + learnMore: getString("learn_more_label", "Learn more"), + learnMoreURL: `https://tb-manual.torproject.org/${getLocale()}/security-settings/`, + restoreDefaults: getString("restore_defaults", "Restore Defaults"), + advancedSecuritySettings: getString( + "advanced_security_settings", + "Advanced Security Settings\u2026" + ), + }; + return retval; + })() /* Security Level Strings */, + + /* + Tor about:preferences#tor Strings + */ + settings: (function() { + let tsb = new TorDTDStringBundle( + ["chrome://torlauncher/locale/network-settings.dtd"], + "" + ); + let getString = function(key, fallback) { + return tsb.getString(key, fallback); + }; + + let retval = { + categoryTitle: getString("torPreferences.categoryTitle", "Tor"), + torPreferencesHeading: getString( + "torPreferences.torSettings", + "Tor Settings" + ), + torPreferencesDescription: getString( + "torPreferences.torSettingsDescription", + "Tor Browser routes your traffic over the Tor Network, run by thousands of volunteers around the world." + ), + learnMore: getString("torPreferences.learnMore", "Learn More"), + bridgesHeading: getString("torPreferences.bridges", "Bridges"), + bridgesDescription: getString( + "torPreferences.bridgesDescription", + "Bridges help you access the Tor Network in places where Tor is blocked. Depending on where you are, one bridge may work better than another." + ), + useBridge: getString("torPreferences.useBridge", "Use a bridge"), + selectBridge: getString( + "torsettings.useBridges.default", + "Select a bridge" + ), + requestBridgeFromTorProject: getString( + "torsettings.useBridges.bridgeDB", + "Request a bridge from torproject.org" + ), + requestNewBridge: getString( + "torPreferences.requestNewBridge", + "Request a New Bridge\u2026" + ), + provideBridge: getString( + "torPreferences.provideBridge", + "Provide a bridge" + ), + provideBridgeDirections: getString( + "torsettings.useBridges.label", + "Enter bridge information from a trusted source." + ), + provideBridgePlaceholder: getString( + "torsettings.useBridges.placeholder", + "type address:port (one per line)" + ), + advancedHeading: getString("torPreferences.advanced", "Advanced"), + advancedDescription: getString( + "torPreferences.advancedDescription", + "Configure how Tor Browser connects to the internet." + ), + useLocalProxy: getString("torsettings.useProxy.checkbox", "I use a proxy to connect to the Internet"), + proxyType: getString("torsettings.useProxy.type", "Proxy Type"), + proxyTypeSOCKS4: getString("torsettings.useProxy.type.socks4", "SOCKS4"), + proxyTypeSOCKS5: getString("torsettings.useProxy.type.socks5", "SOCKS5"), + proxyTypeHTTP: getString("torsettings.useProxy.type.http", "HTTP/HTTPS"), + proxyAddress: getString("torsettings.useProxy.address", "Address"), + proxyAddressPlaceholder: getString( + "torsettings.useProxy.address.placeholder", + "IP address or hostname" + ), + proxyPort: getString("torsettings.useProxy.port", "Port"), + proxyUsername: getString("torsettings.useProxy.username", "Username"), + proxyPassword: getString("torsettings.useProxy.password", "Password"), + proxyUsernamePasswordPlaceholder: getString( + "torsettings.optional", + "Optional" + ), + useFirewall: getString( + "torsettings.firewall.checkbox", + "This computer goes through a firewall that only allows connections to certain ports" + ), + allowedPorts: getString( + "torsettings.firewall.allowedPorts", + "Allowed Ports" + ), + allowedPortsPlaceholder: getString( + "torPreferences.firewallPortsPlaceholder", + "Comma-seperated values" + ), + requestBridgeDialogTitle: getString( + "torPreferences.requestBridgeDialogTitle", + "Request Bridge" + ), + submitCaptcha: getString( + "torsettings.useBridges.captchaSubmit", + "Submit" + ), + contactingBridgeDB: getString( + "torPreferences.requestBridgeDialogWaitPrompt", + "Contacting BridgeDB. Please Wait." + ), + solveTheCaptcha: getString( + "torPreferences.requestBridgeDialogSolvePrompt", + "Solve the CAPTCHA to request a bridge." + ), + captchaTextboxPlaceholder: getString( + "torsettings.useBridges.captchaSolution.placeholder", + "Enter the characters from the image" + ), + incorrectCaptcha: getString( + "torPreferences.requestBridgeErrorBadSolution", + "The solution is not correct. Please try again." + ), + showTorDaemonLogs: getString( + "torPreferences.viewTorLogs", + "View the Tor logs." + ), + showLogs: getString("torPreferences.viewLogs", "View Logs\u2026"), + torLogDialogTitle: getString( + "torPreferences.torLogsDialogTitle", + "Tor Logs" + ), + copyLog: getString("torsettings.copyLog", "Copy Tor Log to Clipboard"), + + learnMoreTorBrowserURL: `https://tb-manual.torproject.org/${getLocale()}/about/`, + learnMoreBridgesURL: `https://tb-manual.torproject.org/${getLocale()}/bridges/`, + learnMoreNetworkSettingsURL: `about:blank`, + }; + + return retval; + })() /* Tor Network Settings Strings */, + + /* + Tor Onion Services Strings, e.g., for the authentication prompt. + */ + onionServices: (function() { + let tsb = new TorPropertyStringBundle( + "chrome://torbutton/locale/torbutton.properties", + "onionServices." + ); + let getString = function(key, fallback) { + return tsb.getString(key, fallback); + }; + + const kProblemLoadingSiteFallback = "Problem Loading Onionsite"; + const kLongDescFallback = "Details: %S"; + + let retval = { + learnMore: getString("learnMore", "Learn more"), + learnMoreURL: `https://support.torproject.org/${getLocale()}/onionservices/client-auth/`, + errorPage: { + browser: getString("errorPage.browser", "Browser"), + network: getString("errorPage.network", "Network"), + onionSite: getString("errorPage.onionSite", "Onionsite"), + }, + descNotFound: { // Tor SOCKS error 0xF0 + pageTitle: getString("descNotFound.pageTitle", kProblemLoadingSiteFallback), + header: getString("descNotFound.header", "Onionsite Not Found"), + longDescription: getString("descNotFound.longDescription", kLongDescFallback), + }, + descInvalid: { // Tor SOCKS error 0xF1 + pageTitle: getString("descInvalid.pageTitle", kProblemLoadingSiteFallback), + header: getString("descInvalid.header", "Onionsite Cannot Be Reached"), + longDescription: getString("descInvalid.longDescription", kLongDescFallback), + }, + introFailed: { // Tor SOCKS error 0xF2 + pageTitle: getString("introFailed.pageTitle", kProblemLoadingSiteFallback), + header: getString("introFailed.header", "Onionsite Has Disconnected"), + longDescription: getString("introFailed.longDescription", kLongDescFallback), + }, + rendezvousFailed: { // Tor SOCKS error 0xF3 + pageTitle: getString("rendezvousFailed.pageTitle", kProblemLoadingSiteFallback), + header: getString("rendezvousFailed.header", "Unable to Connect to Onionsite"), + longDescription: getString("rendezvousFailed.longDescription", kLongDescFallback), + }, + clientAuthMissing: { // Tor SOCKS error 0xF4 + pageTitle: getString("clientAuthMissing.pageTitle", "Authorization Required"), + header: getString("clientAuthMissing.header", "Onionsite Requires Authentication"), + longDescription: getString("clientAuthMissing.longDescription", kLongDescFallback), + }, + clientAuthIncorrect: { // Tor SOCKS error 0xF5 + pageTitle: getString("clientAuthIncorrect.pageTitle", "Authorization Failed"), + header: getString("clientAuthIncorrect.header", "Onionsite Authentication Failed"), + longDescription: getString("clientAuthIncorrect.longDescription", kLongDescFallback), + }, + badAddress: { // Tor SOCKS error 0xF6 + pageTitle: getString("badAddress.pageTitle", kProblemLoadingSiteFallback), + header: getString("badAddress.header", "Invalid Onionsite Address"), + longDescription: getString("badAddress.longDescription", kLongDescFallback), + }, + introTimedOut: { // Tor SOCKS error 0xF7 + pageTitle: getString("introTimedOut.pageTitle", kProblemLoadingSiteFallback), + header: getString("introTimedOut.header", "Onionsite Circuit Creation Timed Out"), + longDescription: getString("introTimedOut.longDescription", kLongDescFallback), + }, + authPrompt: { + description: + getString("authPrompt.description2", "%S is requesting that you authenticate."), + keyPlaceholder: getString("authPrompt.keyPlaceholder", "Enter your key"), + done: getString("authPrompt.done", "Done"), + doneAccessKey: getString("authPrompt.doneAccessKey", "d"), + invalidKey: getString("authPrompt.invalidKey", "Invalid key"), + failedToSetKey: + getString("authPrompt.failedToSetKey", "Failed to set key"), + }, + authPreferences: { + header: getString("authPreferences.header", "Onion Services Authentication"), + overview: getString("authPreferences.overview", "Some onion services require that you identify yourself with a key"), + savedKeys: getString("authPreferences.savedKeys", "Saved Keys"), + dialogTitle: getString("authPreferences.dialogTitle", "Onion Services Keys"), + dialogIntro: getString("authPreferences.dialogIntro", "Keys for the following onionsites are stored on your computer"), + onionSite: getString("authPreferences.onionSite", "Onionsite"), + onionKey: getString("authPreferences.onionKey", "Key"), + remove: getString("authPreferences.remove", "Remove"), + removeAll: getString("authPreferences.removeAll", "Remove All"), + failedToGetKeys: getString("authPreferences.failedToGetKeys", "Failed to get keys"), + failedToRemoveKey: getString("authPreferences.failedToRemoveKey", "Failed to remove key"), + }, + }; + + return retval; + })() /* Tor Onion Services Strings */, + + /* + OnionLocation + */ + onionLocation: (function() { + const tsb = new TorPropertyStringBundle( + ["chrome://torbutton/locale/torbutton.properties"], + "onionLocation." + ); + const getString = function(key, fallback) { + return tsb.getString(key, fallback); + }; + + const retval = { + alwaysPrioritize: getString( + "alwaysPrioritize", + "Always Prioritize Onionsites" + ), + alwaysPrioritizeAccessKey: getString("alwaysPrioritizeAccessKey", "a"), + notNow: getString("notNow", "Not Now"), + notNowAccessKey: getString("notNowAccessKey", "n"), + description: getString( + "description", + "Website publishers can protect users by adding a security layer. This prevents eavesdroppers from knowing that you are the one visiting that website." + ), + tryThis: getString("tryThis", "Try this: Onionsite"), + onionAvailable: getString("onionAvailable", "Onionsite available"), + learnMore: getString("learnMore", "Learn more"), + learnMoreURL: `https://tb-manual.torproject.org/${getLocale()}/onion-services/`, + always: getString("always", "Always"), + askEverytime: getString("askEverytime", "Ask you every time"), + prioritizeOnionsDescription: getString( + "prioritizeOnionsDescription", + "Prioritize onionsites when they are available." + ), + onionServicesTitle: getString("onionServicesTitle", "Onion Services"), + }; + + return retval; + })() /* OnionLocation */, + + /* + Tor Deamon Configuration Key Strings + */ + + // TODO: proper camel case + configKeys: { + /* Bridge Conf Settings */ + useBridges: "UseBridges", + bridgeList: "Bridge", + /* Proxy Conf Strings */ + socks4Proxy: "Socks4Proxy", + socks5Proxy: "Socks5Proxy", + socks5ProxyUsername: "Socks5ProxyUsername", + socks5ProxyPassword: "Socks5ProxyPassword", + httpsProxy: "HTTPSProxy", + httpsProxyAuthenticator: "HTTPSProxyAuthenticator", + /* Firewall Conf Strings */ + reachableAddresses: "ReachableAddresses", + + /* BridgeDB Strings */ + clientTransportPlugin: "ClientTransportPlugin", + }, + + /* + about:config preference keys + */ + + preferenceKeys: { + defaultBridgeType: "extensions.torlauncher.default_bridge_type", + recommendedBridgeType: + "extensions.torlauncher.default_bridge_recommended_type", + }, + + /* + about:config preference branches + */ + preferenceBranches: { + defaultBridge: "extensions.torlauncher.default_bridge.", + bridgeDBBridges: "extensions.torlauncher.bridgedb_bridge.", + }, +}; diff --git a/browser/modules/moz.build b/browser/modules/moz.build index b069f1b641f7..3774c12f4ef0 100644 --- a/browser/modules/moz.build +++ b/browser/modules/moz.build @@ -152,6 +152,7 @@ EXTRA_JS_MODULES += [ "TabsList.jsm", "TabUnloader.jsm", "ThemeVariableMap.jsm", + "TorStrings.jsm", "TransientPrefs.jsm", "webrtcUI.jsm", "ZoomUI.jsm",
1 0
0 0
[tor-browser/tor-browser-87.0b4-10.5-1] Bug 16439: Remove screencasting code
by sysrqb@torproject.org 11 Mar '21

11 Mar '21
commit 38cce45a1a06f24f1140d3e9c0773de1b67981b1 Author: Kathy Brade <brade(a)pearlcrescent.com> Date: Wed Jun 24 11:01:11 2015 -0400 Bug 16439: Remove screencasting code We avoid including the screencasting code on mobile (it got ripped out for desktop in bug 1393582) by simply excluding the related JS modules from Tor Browser. --- toolkit/modules/moz.build | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/toolkit/modules/moz.build b/toolkit/modules/moz.build index cd4a66093c53..a5517dfad326 100644 --- a/toolkit/modules/moz.build +++ b/toolkit/modules/moz.build @@ -263,10 +263,11 @@ if "Android" != CONFIG["OS_TARGET"]: ] else: DEFINES["ANDROID"] = True - EXTRA_JS_MODULES += [ - "secondscreen/RokuApp.jsm", - "secondscreen/SimpleServiceDiscovery.jsm", - ] + if not CONFIG["TOR_BROWSER_VERSION"]: + EXTRA_JS_MODULES += [ + "secondscreen/RokuApp.jsm", + "secondscreen/SimpleServiceDiscovery.jsm", + ] if CONFIG["MOZ_WIDGET_TOOLKIT"] == "windows":
1 0
0 0
[tor-browser/tor-browser-87.0b4-10.5-1] Bug 13028: Prevent potential proxy bypass cases.
by sysrqb@torproject.org 11 Mar '21

11 Mar '21
commit 63a141c3592b19fa8c564a2f39a7449a097d30ad Author: Mike Perry <mikeperry-git(a)torproject.org> Date: Mon Sep 29 14:30:19 2014 -0700 Bug 13028: Prevent potential proxy bypass cases. It looks like these cases should only be invoked in the NSS command line tools, and not the browser, but I decided to patch them anyway because there literally is a maze of network function pointers being passed around, and it's very hard to tell if some random code might not pass in the proper proxied versions of the networking code here by accident. --- security/nss/lib/certhigh/ocsp.c | 8 ++++++++ .../lib/libpkix/pkix_pl_nss/module/pkix_pl_socket.c | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/security/nss/lib/certhigh/ocsp.c b/security/nss/lib/certhigh/ocsp.c index cea8456606bf..86fa971cfbef 100644 --- a/security/nss/lib/certhigh/ocsp.c +++ b/security/nss/lib/certhigh/ocsp.c @@ -2932,6 +2932,14 @@ ocsp_ConnectToHost(const char *host, PRUint16 port) PRNetAddr addr; char *netdbbuf = NULL; + // XXX: Do we need a unittest ifdef here? We don't want to break the tests, but + // we want to ensure nothing can ever hit this code in production. +#if 1 + printf("Tor Browser BUG: Attempted OSCP direct connect to %s, port %u\n", host, + port); + goto loser; +#endif + sock = PR_NewTCPSocket(); if (sock == NULL) goto loser; diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_socket.c b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_socket.c index e8698376b5be..85791d84a932 100644 --- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_socket.c +++ b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_socket.c @@ -1334,6 +1334,13 @@ pkix_pl_Socket_Create( plContext), PKIX_COULDNOTCREATESOCKETOBJECT); + // XXX: Do we need a unittest ifdef here? We don't want to break the tests, but + // we want to ensure nothing can ever hit this code in production. +#if 1 + printf("Tor Browser BUG: Attempted pkix direct socket connect\n"); + PKIX_ERROR(PKIX_PRNEWTCPSOCKETFAILED); +#endif + socket->isServer = isServer; socket->timeout = timeout; socket->clientSock = NULL; @@ -1433,6 +1440,13 @@ pkix_pl_Socket_CreateByName( localCopyName = PL_strdup(serverName); + // XXX: Do we need a unittest ifdef here? We don't want to break the tests, but + // we want to ensure nothing can ever hit this code in production. +#if 1 + printf("Tor Browser BUG: Attempted pkix direct connect to %s\n", serverName); + PKIX_ERROR(PKIX_PRNEWTCPSOCKETFAILED); +#endif + sepPtr = strchr(localCopyName, ':'); /* First strip off the portnum, if present, from the end of the name */ if (sepPtr) { @@ -1582,6 +1596,13 @@ pkix_pl_Socket_CreateByHostAndPort( PKIX_ENTER(SOCKET, "pkix_pl_Socket_CreateByHostAndPort"); PKIX_NULLCHECK_THREE(hostname, pStatus, pSocket); + // XXX: Do we need a unittest ifdef here? We don't want to break the tests, but + // we want to ensure nothing can ever hit this code in production. +#if 1 + printf("Tor Browser BUG: Attempted pkix direct connect to %s, port %u\n", hostname, + portnum); + PKIX_ERROR(PKIX_PRNEWTCPSOCKETFAILED); +#endif prstatus = PR_GetHostByName(hostname, buf, sizeof(buf), &hostent);
1 0
0 0
[tor-browser/tor-browser-87.0b4-10.5-1] Bug 12974: Disable NTLM and Negotiate HTTP Auth
by sysrqb@torproject.org 11 Mar '21

11 Mar '21
commit 82b8c9c0dd586159fa82a9bcf37b0b92154ef321 Author: Mike Perry <mikeperry-git(a)torproject.org> Date: Wed Aug 27 15:19:10 2014 -0700 Bug 12974: Disable NTLM and Negotiate HTTP Auth This is technically an embargoed Mozilla bug, so I probably shouldn't provide too many details. Suffice to say that NTLM and Negotiate auth are bad for Tor users, and I doubt very many (or any of them) actually need it. The Mozilla bug is https://bugzilla.mozilla.org/show_bug.cgi?id=1046421 --- extensions/auth/nsHttpNegotiateAuth.cpp | 4 ++++ netwerk/protocol/http/nsHttpNTLMAuth.cpp | 3 +++ 2 files changed, 7 insertions(+) diff --git a/extensions/auth/nsHttpNegotiateAuth.cpp b/extensions/auth/nsHttpNegotiateAuth.cpp index 00d089163156..e83347188ff2 100644 --- a/extensions/auth/nsHttpNegotiateAuth.cpp +++ b/extensions/auth/nsHttpNegotiateAuth.cpp @@ -154,6 +154,10 @@ nsHttpNegotiateAuth::ChallengeReceived(nsIHttpAuthenticableChannel* authChannel, nsIAuthModule* rawModule = (nsIAuthModule*)*continuationState; *identityInvalid = false; + + /* Always fail Negotiate auth for Tor Browser. We don't need it. */ + return NS_ERROR_ABORT; + if (rawModule) { return NS_OK; } diff --git a/netwerk/protocol/http/nsHttpNTLMAuth.cpp b/netwerk/protocol/http/nsHttpNTLMAuth.cpp index 0a30de051014..891aaadfd758 100644 --- a/netwerk/protocol/http/nsHttpNTLMAuth.cpp +++ b/netwerk/protocol/http/nsHttpNTLMAuth.cpp @@ -168,6 +168,9 @@ nsHttpNTLMAuth::ChallengeReceived(nsIHttpAuthenticableChannel* channel, *identityInvalid = false; + /* Always fail Negotiate auth for Tor Browser. We don't need it. */ + return NS_ERROR_ABORT; + // Start a new auth sequence if the challenge is exactly "NTLM". // If native NTLM auth apis are available and enabled through prefs, // try to use them.
1 0
0 0
[tor-browser/tor-browser-87.0b4-10.5-1] Bug 9173: Change the default Firefox profile directory to be TBB-relative.
by sysrqb@torproject.org 11 Mar '21

11 Mar '21
commit 8bb97101c7abbf6a87f64905b4d3bfb5b211de1d Author: Kathy Brade <brade(a)pearlcrescent.com> Date: Fri Oct 18 15:20:06 2013 -0400 Bug 9173: Change the default Firefox profile directory to be TBB-relative. This should eliminate our need to rely on a wrapper script that sets /Users/arthur and launches Firefox with -profile. --- toolkit/profile/nsToolkitProfileService.cpp | 5 +- toolkit/xre/nsAppRunner.cpp | 2 +- toolkit/xre/nsConsoleWriter.cpp | 2 +- toolkit/xre/nsXREDirProvider.cpp | 149 ++++++---------------------- toolkit/xre/nsXREDirProvider.h | 16 +-- xpcom/io/nsAppFileLocationProvider.cpp | 97 +++++++----------- 6 files changed, 84 insertions(+), 187 deletions(-) diff --git a/toolkit/profile/nsToolkitProfileService.cpp b/toolkit/profile/nsToolkitProfileService.cpp index 0ef010726df1..38592720785b 100644 --- a/toolkit/profile/nsToolkitProfileService.cpp +++ b/toolkit/profile/nsToolkitProfileService.cpp @@ -724,10 +724,11 @@ nsresult nsToolkitProfileService::Init() { NS_ASSERTION(gDirServiceProvider, "No dirserviceprovider!"); nsresult rv; - rv = nsXREDirProvider::GetUserAppDataDirectory(getter_AddRefs(mAppData)); + rv = gDirServiceProvider->GetUserAppDataDirectory(getter_AddRefs(mAppData)); NS_ENSURE_SUCCESS(rv, rv); - rv = nsXREDirProvider::GetUserLocalDataDirectory(getter_AddRefs(mTempData)); + rv = + gDirServiceProvider->GetUserLocalDataDirectory(getter_AddRefs(mTempData)); NS_ENSURE_SUCCESS(rv, rv); rv = mAppData->Clone(getter_AddRefs(mProfileDBFile)); diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index 7576803b36dd..d894ed34f291 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -3681,7 +3681,7 @@ int XREMain::XRE_mainInit(bool* aExitFlag) { if ((mAppData->flags & NS_XRE_ENABLE_CRASH_REPORTER) && NS_SUCCEEDED(CrashReporter::SetExceptionHandler(xreBinDirectory))) { nsCOMPtr<nsIFile> file; - rv = nsXREDirProvider::GetUserAppDataDirectory(getter_AddRefs(file)); + rv = mDirProvider.GetUserAppDataDirectory(getter_AddRefs(file)); if (NS_SUCCEEDED(rv)) { CrashReporter::SetUserAppDataDirectory(file); } diff --git a/toolkit/xre/nsConsoleWriter.cpp b/toolkit/xre/nsConsoleWriter.cpp index d89ea3bde31d..4a9a6d28034a 100644 --- a/toolkit/xre/nsConsoleWriter.cpp +++ b/toolkit/xre/nsConsoleWriter.cpp @@ -29,7 +29,7 @@ void WriteConsoleLog() { } else { if (!gLogConsoleErrors) return; - rv = nsXREDirProvider::GetUserAppDataDirectory(getter_AddRefs(lfile)); + rv = gDirServiceProvider->GetUserAppDataDirectory(getter_AddRefs(lfile)); if (NS_FAILED(rv)) return; lfile->AppendNative("console.log"_ns); diff --git a/toolkit/xre/nsXREDirProvider.cpp b/toolkit/xre/nsXREDirProvider.cpp index c83f1b7de17d..4a675eb79fa0 100644 --- a/toolkit/xre/nsXREDirProvider.cpp +++ b/toolkit/xre/nsXREDirProvider.cpp @@ -32,6 +32,7 @@ #include "nsArrayEnumerator.h" #include "nsEnumeratorUtils.h" #include "nsReadableUtils.h" +#include "nsXPCOMPrivate.h" // for XPCOM_FILE_PATH_SEPARATOR #include "SpecialSystemDirectory.h" @@ -249,9 +250,6 @@ nsresult nsXREDirProvider::GetUserProfilesRootDir(nsIFile** aResult) { nsresult rv = GetUserDataDirectory(getter_AddRefs(file), false); if (NS_SUCCEEDED(rv)) { -#if !defined(XP_UNIX) || defined(XP_MACOSX) - rv = file->AppendNative("Profiles"_ns); -#endif // We must create the profile directory here if it does not exist. nsresult tmp = EnsureDirectoryExists(file); if (NS_FAILED(tmp)) { @@ -267,9 +265,6 @@ nsresult nsXREDirProvider::GetUserProfilesLocalDir(nsIFile** aResult) { nsresult rv = GetUserDataDirectory(getter_AddRefs(file), true); if (NS_SUCCEEDED(rv)) { -#if !defined(XP_UNIX) || defined(XP_MACOSX) - rv = file->AppendNative("Profiles"_ns); -#endif // We must create the profile directory here if it does not exist. nsresult tmp = EnsureDirectoryExists(file); if (NS_FAILED(tmp)) { @@ -1417,7 +1412,7 @@ nsresult nsXREDirProvider::SetUserDataProfileDirectory(nsCOMPtr<nsIFile>& aFile, nsresult nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile, bool aLocal) { // Copied from nsAppFileLocationProvider (more or less) - nsresult rv; + NS_ENSURE_ARG_POINTER(aFile); nsCOMPtr<nsIFile> localDir; if (aLocal && gDataDirHomeLocal) { @@ -1427,80 +1422,39 @@ nsresult nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile, return gDataDirHome->Clone(aFile); } -#if defined(XP_MACOSX) - FSRef fsRef; - OSType folderType; - if (aLocal) { - folderType = kCachedDataFolderType; - } else { -# ifdef MOZ_THUNDERBIRD - folderType = kDomainLibraryFolderType; -# else - folderType = kApplicationSupportFolderType; -# endif - } - OSErr err = ::FSFindFolder(kUserDomain, folderType, kCreateFolder, &fsRef); - NS_ENSURE_FALSE(err, NS_ERROR_FAILURE); - - rv = NS_NewNativeLocalFile(""_ns, true, getter_AddRefs(localDir)); + nsresult rv = GetAppDir()->Clone(getter_AddRefs(localDir)); NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr<nsILocalFileMac> dirFileMac = do_QueryInterface(localDir); - NS_ENSURE_TRUE(dirFileMac, NS_ERROR_UNEXPECTED); - - rv = dirFileMac->InitWithFSRef(&fsRef); - NS_ENSURE_SUCCESS(rv, rv); + int levelsToRemove = 1; // In FF21+, appDir points to browser subdirectory. +#if defined(XP_MACOSX) + levelsToRemove += 2; +#endif + while (localDir && (levelsToRemove > 0)) { + // When crawling up the hierarchy, components named "." do not count. + nsAutoCString removedName; + rv = localDir->GetNativeLeafName(removedName); + NS_ENSURE_SUCCESS(rv, rv); + bool didRemove = !removedName.Equals("."); - localDir = dirFileMac; -#elif defined(XP_IOS) - nsAutoCString userDir; - if (GetUIKitDirectory(aLocal, userDir)) { - rv = NS_NewNativeLocalFile(userDir, true, getter_AddRefs(localDir)); - } else { - rv = NS_ERROR_FAILURE; - } - NS_ENSURE_SUCCESS(rv, rv); -#elif defined(XP_WIN) - nsString path; - if (aLocal) { - rv = GetShellFolderPath(FOLDERID_LocalAppData, path); - if (NS_FAILED(rv)) rv = GetRegWindowsAppDataFolder(aLocal, path); - } - if (!aLocal || NS_FAILED(rv)) { - rv = GetShellFolderPath(FOLDERID_RoamingAppData, path); - if (NS_FAILED(rv)) { - if (!aLocal) rv = GetRegWindowsAppDataFolder(aLocal, path); - } + // Remove a directory component. + nsCOMPtr<nsIFile> parentDir; + rv = localDir->GetParent(getter_AddRefs(parentDir)); + NS_ENSURE_SUCCESS(rv, rv); + localDir = parentDir; + if (didRemove) --levelsToRemove; } - NS_ENSURE_SUCCESS(rv, rv); - rv = NS_NewLocalFile(path, true, getter_AddRefs(localDir)); -#elif defined(XP_UNIX) - const char* homeDir = getenv("HOME"); - if (!homeDir || !*homeDir) return NS_ERROR_FAILURE; + if (!localDir) return NS_ERROR_FAILURE; -# ifdef ANDROID /* We want (ProfD == ProfLD) on Android. */ - aLocal = false; -# endif + rv = localDir->AppendRelativeNativePath("TorBrowser" XPCOM_FILE_PATH_SEPARATOR + "Data" XPCOM_FILE_PATH_SEPARATOR + "Browser"_ns); + NS_ENSURE_SUCCESS(rv, rv); if (aLocal) { - // If $XDG_CACHE_HOME is defined use it, otherwise use $HOME/.cache. - const char* cacheHome = getenv("XDG_CACHE_HOME"); - if (cacheHome && *cacheHome) { - rv = NS_NewNativeLocalFile(nsDependentCString(cacheHome), true, - getter_AddRefs(localDir)); - } else { - rv = NS_NewNativeLocalFile(nsDependentCString(homeDir), true, - getter_AddRefs(localDir)); - if (NS_SUCCEEDED(rv)) rv = localDir->AppendNative(".cache"_ns); - } - } else { - rv = NS_NewNativeLocalFile(nsDependentCString(homeDir), true, - getter_AddRefs(localDir)); + rv = localDir->AppendNative("Caches"_ns); + NS_ENSURE_SUCCESS(rv, rv); } -#else -# error "Don't know how to get product dir on your platform" -#endif NS_IF_ADDREF(*aFile = localDir); return rv; @@ -1683,39 +1637,23 @@ nsresult nsXREDirProvider::AppendProfilePath(nsIFile* aFile, bool aLocal) { } nsAutoCString profile; - nsAutoCString appName; - nsAutoCString vendor; if (gAppData->profile) { profile = gAppData->profile; - } else { - appName = gAppData->name; - vendor = gAppData->vendor; } - nsresult rv = NS_OK; + nsresult rv = NS_ERROR_FAILURE; #if defined(XP_MACOSX) if (!profile.IsEmpty()) { rv = AppendProfileString(aFile, profile.get()); - } else { - // Note that MacOS ignores the vendor when creating the profile hierarchy - - // all application preferences directories live alongside one another in - // ~/Library/Application Support/ - rv = aFile->AppendNative(appName); + NS_ENSURE_SUCCESS(rv, rv); } - NS_ENSURE_SUCCESS(rv, rv); #elif defined(XP_WIN) if (!profile.IsEmpty()) { rv = AppendProfileString(aFile, profile.get()); - } else { - if (!vendor.IsEmpty()) { - rv = aFile->AppendNative(vendor); - NS_ENSURE_SUCCESS(rv, rv); - } - rv = aFile->AppendNative(appName); + NS_ENSURE_SUCCESS(rv, rv); } - NS_ENSURE_SUCCESS(rv, rv); #elif defined(ANDROID) // The directory used for storing profiles @@ -1725,11 +1663,6 @@ nsresult nsXREDirProvider::AppendProfilePath(nsIFile* aFile, bool aLocal) { rv = aFile->AppendNative(nsDependentCString("mozilla")); NS_ENSURE_SUCCESS(rv, rv); #elif defined(XP_UNIX) - nsAutoCString folder; - // Make it hidden (by starting with "."), except when local (the - // profile is already under ~/.cache or XDG_CACHE_HOME). - if (!aLocal) folder.Assign('.'); - if (!profile.IsEmpty()) { // Skip any leading path characters const char* profileStart = profile.get(); @@ -1737,32 +1670,16 @@ nsresult nsXREDirProvider::AppendProfilePath(nsIFile* aFile, bool aLocal) { // On the off chance that someone wanted their folder to be hidden don't // let it become ".." - if (*profileStart == '.' && !aLocal) profileStart++; + if (*profileStart == '.') profileStart++; + // Make it hidden (by starting with "."). + nsAutoCString folder("."); folder.Append(profileStart); ToLowerCase(folder); rv = AppendProfileString(aFile, folder.BeginReading()); - } else { - if (!vendor.IsEmpty()) { - folder.Append(vendor); - ToLowerCase(folder); - - rv = aFile->AppendNative(folder); - NS_ENSURE_SUCCESS(rv, rv); - - folder.Truncate(); - } - - // This can be the case in tests. - if (!appName.IsEmpty()) { - folder.Append(appName); - ToLowerCase(folder); - - rv = aFile->AppendNative(folder); - } + NS_ENSURE_SUCCESS(rv, rv); } - NS_ENSURE_SUCCESS(rv, rv); #else # error "Don't know how to get profile path on your platform" diff --git a/toolkit/xre/nsXREDirProvider.h b/toolkit/xre/nsXREDirProvider.h index e55b4e153c56..b9678d4ec577 100644 --- a/toolkit/xre/nsXREDirProvider.h +++ b/toolkit/xre/nsXREDirProvider.h @@ -63,15 +63,19 @@ class nsXREDirProvider final : public nsIDirectoryServiceProvider2, void DoShutdown(); - static nsresult GetUserAppDataDirectory(nsIFile** aFile) { + nsresult GetUserAppDataDirectory(nsIFile** aFile) { return GetUserDataDirectory(aFile, false); } - static nsresult GetUserLocalDataDirectory(nsIFile** aFile) { + nsresult GetUserLocalDataDirectory(nsIFile** aFile) { return GetUserDataDirectory(aFile, true); } // GetUserDataDirectory gets the profile path from gAppData. - static nsresult GetUserDataDirectory(nsIFile** aFile, bool aLocal); + + // This function now calls GetAppDir(), so it cannot be static anymore. + // The same happens with all the functions (in)directly calling this one (the + // rest of Get*Directory functions in this file) + nsresult GetUserDataDirectory(nsIFile** aFile, bool aLocal); /* make sure you clone it, if you need to do stuff to it */ nsIFile* GetGREDir() { return mGREDir; } @@ -112,9 +116,9 @@ class nsXREDirProvider final : public nsIDirectoryServiceProvider2, protected: nsresult GetFilesInternal(const char* aProperty, nsISimpleEnumerator** aResult); - static nsresult GetUserDataDirectoryHome(nsIFile** aFile, bool aLocal); - static nsresult GetSysUserExtensionsDirectory(nsIFile** aFile); - static nsresult GetSysUserExtensionsDevDirectory(nsIFile** aFile); + nsresult GetUserDataDirectoryHome(nsIFile** aFile, bool aLocal); + nsresult GetSysUserExtensionsDirectory(nsIFile** aFile); + nsresult GetSysUserExtensionsDevDirectory(nsIFile** aFile); #if defined(XP_UNIX) || defined(XP_MACOSX) static nsresult GetSystemExtensionsDirectory(nsIFile** aFile); #endif diff --git a/xpcom/io/nsAppFileLocationProvider.cpp b/xpcom/io/nsAppFileLocationProvider.cpp index ef974f99048f..2bbcee92aedb 100644 --- a/xpcom/io/nsAppFileLocationProvider.cpp +++ b/xpcom/io/nsAppFileLocationProvider.cpp @@ -15,6 +15,7 @@ #include "nsSimpleEnumerator.h" #include "prenv.h" #include "nsCRT.h" +#include "nsXPCOMPrivate.h" // for XPCOM_FILE_PATH_SEPARATOR #if defined(MOZ_WIDGET_COCOA) # include <Carbon/Carbon.h> # include "nsILocalFileMac.h" @@ -233,9 +234,8 @@ nsresult nsAppFileLocationProvider::CloneMozBinDirectory(nsIFile** aLocalFile) { // GetProductDirectory - Gets the directory which contains the application data // folder // -// UNIX : ~/.mozilla/ -// WIN : <Application Data folder on user's machine>\Mozilla -// Mac : :Documents:Mozilla: +// UNIX and WIN : <App Folder>/TorBrowser/Data/Browser +// Mac : <App Folder>/../../TorBrowser/Data/Browser //---------------------------------------------------------------------------------------- nsresult nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile, bool aLocal) { @@ -247,49 +247,45 @@ nsresult nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile, bool exists; nsCOMPtr<nsIFile> localDir; -#if defined(MOZ_WIDGET_COCOA) - FSRef fsRef; - OSType folderType = - aLocal ? (OSType)kCachedDataFolderType : (OSType)kDomainLibraryFolderType; - OSErr err = ::FSFindFolder(kUserDomain, folderType, kCreateFolder, &fsRef); - if (err) { - return NS_ERROR_FAILURE; + rv = CloneMozBinDirectory(getter_AddRefs(localDir)); + NS_ENSURE_SUCCESS(rv, rv); + + int levelsToRemove = 1; // In FF21+, bin dir points to browser subdirectory. +#if defined(XP_MACOSX) + levelsToRemove += 2; +#endif + while (localDir && (levelsToRemove > 0)) { + // When crawling up the hierarchy, components named "." do not count. + nsAutoCString removedName; + rv = localDir->GetNativeLeafName(removedName); + NS_ENSURE_SUCCESS(rv, rv); + bool didRemove = !removedName.Equals("."); + + // Remove a directory component. + nsCOMPtr<nsIFile> parentDir; + rv = localDir->GetParent(getter_AddRefs(parentDir)); + NS_ENSURE_SUCCESS(rv, rv); + localDir = parentDir; + + if (didRemove) { + --levelsToRemove; + } } - NS_NewLocalFile(u""_ns, true, getter_AddRefs(localDir)); + if (!localDir) { return NS_ERROR_FAILURE; } - nsCOMPtr<nsILocalFileMac> localDirMac(do_QueryInterface(localDir)); - rv = localDirMac->InitWithFSRef(&fsRef); - if (NS_FAILED(rv)) { - return rv; - } -#elif defined(XP_WIN) - nsCOMPtr<nsIProperties> directoryService = - do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv); - if (NS_FAILED(rv)) { - return rv; - } - const char* prop = aLocal ? NS_WIN_LOCAL_APPDATA_DIR : NS_WIN_APPDATA_DIR; - rv = directoryService->Get(prop, NS_GET_IID(nsIFile), - getter_AddRefs(localDir)); - if (NS_FAILED(rv)) { - return rv; - } -#elif defined(XP_UNIX) - rv = NS_NewNativeLocalFile(nsDependentCString(PR_GetEnv("HOME")), true, - getter_AddRefs(localDir)); - if (NS_FAILED(rv)) { - return rv; - } -#else -# error dont_know_how_to_get_product_dir_on_your_platform -#endif - rv = localDir->AppendRelativeNativePath(DEFAULT_PRODUCT_DIR); - if (NS_FAILED(rv)) { - return rv; + rv = localDir->AppendRelativeNativePath("TorBrowser" XPCOM_FILE_PATH_SEPARATOR + "Data" XPCOM_FILE_PATH_SEPARATOR + "Browser"_ns); + NS_ENSURE_SUCCESS(rv, rv); + + if (aLocal) { + rv = localDir->AppendNative("Caches"_ns); + NS_ENSURE_SUCCESS(rv, rv); } + rv = localDir->Exists(&exists); if (NS_SUCCEEDED(rv) && !exists) { @@ -308,10 +304,6 @@ nsresult nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile, //---------------------------------------------------------------------------------------- // GetDefaultUserProfileRoot - Gets the directory which contains each user // profile dir -// -// UNIX : ~/.mozilla/ -// WIN : <Application Data folder on user's machine>\Mozilla\Profiles -// Mac : :Documents:Mozilla:Profiles: //---------------------------------------------------------------------------------------- nsresult nsAppFileLocationProvider::GetDefaultUserProfileRoot( nsIFile** aLocalFile, bool aLocal) { @@ -327,23 +319,6 @@ nsresult nsAppFileLocationProvider::GetDefaultUserProfileRoot( return rv; } -#if defined(MOZ_WIDGET_COCOA) || defined(XP_WIN) - // These 3 platforms share this part of the path - do them as one - rv = localDir->AppendRelativeNativePath("Profiles"_ns); - if (NS_FAILED(rv)) { - return rv; - } - - bool exists; - rv = localDir->Exists(&exists); - if (NS_SUCCEEDED(rv) && !exists) { - rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0775); - } - if (NS_FAILED(rv)) { - return rv; - } -#endif - localDir.forget(aLocalFile); return rv;
1 0
0 0
[tor-browser/tor-browser-87.0b4-10.5-1] Bug 10760: Integrate TorButton to TorBrowser core
by sysrqb@torproject.org 11 Mar '21

11 Mar '21
commit 200024e8cbf0b07e9d87fb2ee15eb3864f931a6c Author: Alex Catarineu <acat(a)torproject.org> Date: Wed Feb 19 23:05:08 2020 +0100 Bug 10760: Integrate TorButton to TorBrowser core Because of the non-restartless nature of Torbutton, it required a two-stage installation process. On mobile, it was a problem, because it was not loading when the user opened the browser for the first time. Moving it to tor-browser and making it a system extension allows it to load when the user opens the browser for first time. Additionally, this patch also fixes Bug 27611. Bug 26321: New Circuit and New Identity menu items Bug 14392: Make about:tor behave like other initial pages. Bug 25013: Add torbutton as a tor-browser submodule --- .gitmodules | 3 ++ browser/base/content/aboutDialog.xhtml | 38 +++++++++++------ browser/base/content/browser-doctype.inc | 6 +++ browser/base/content/browser-menubar.inc | 47 ++++++++++++++++++---- browser/base/content/browser-sets.inc | 2 + browser/base/content/browser.js | 1 + browser/base/content/browser.xhtml | 26 +++++++++++- .../controlcenter/content/identityPanel.inc.xhtml | 44 ++++++++++++++++++++ browser/installer/package-manifest.in | 2 + docshell/base/nsAboutRedirector.cpp | 6 ++- docshell/build/components.conf | 1 + mobile/android/installer/package-manifest.in | 4 ++ toolkit/moz.build | 1 + .../mozapps/extensions/internal/XPIProvider.jsm | 9 +++++ toolkit/torproject/torbutton | 1 + .../lib/environments/browser-window.js | 6 ++- 16 files changed, 172 insertions(+), 25 deletions(-) diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000000..2f03bd8e22df --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "toolkit/torproject/torbutton"] + path = toolkit/torproject/torbutton + url = https://git.torproject.org/torbutton.git diff --git a/browser/base/content/aboutDialog.xhtml b/browser/base/content/aboutDialog.xhtml index 278ba71d7fcc..dd07cc118fb1 100644 --- a/browser/base/content/aboutDialog.xhtml +++ b/browser/base/content/aboutDialog.xhtml @@ -7,11 +7,11 @@ <?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?> <?xml-stylesheet href="chrome://browser/content/aboutDialog.css" type="text/css"?> <?xml-stylesheet href="chrome://branding/content/aboutDialog.css" type="text/css"?> +<?xml-stylesheet href="chrome://torbutton/skin/aboutDialog.css" type="text/css"?> +<!-- We need to include the localization DTDs until we migrate to Fluent --> <!DOCTYPE window [ -#ifdef XP_MACOSX #include browser-doctype.inc -#endif ]> <window xmlns:html="http://www.w3.org/1999/xhtml" @@ -28,7 +28,7 @@ data-l10n-id="aboutDialog-title" #endif role="dialog" - aria-describedby="version distribution distributionId communityDesc contributeDesc trademark" + aria-describedby="version distribution distributionId projectDesc helpDesc trademark trademarkTor" > #ifdef XP_MACOSX #include macWindow.inc.xhtml @@ -146,24 +146,36 @@ <label is="text-link" useoriginprincipal="true" href="about:credits" data-l10n-name="community-exp-creditsLink"/> </description> </vbox> - <description class="text-blurb" id="communityDesc" data-l10n-id="community-2"> - <label is="text-link" href="https://www.mozilla.org/?utm_source=firefox-browser&#38;utm_medium=firefox-…" data-l10n-name="community-mozillaLink"/> - <label is="text-link" useoriginprincipal="true" href="about:credits" data-l10n-name="community-creditsLink"/> + <!-- Keep communityDesc and contributeDesc to avoid JS errors trying to hide them --> + <description class="text-blurb" id="communityDesc" data-l10n-id="community-2" hidden="true"></description> + <description class="text-blurb" id="contributeDesc" data-l10n-id="helpus" hidden="true"></description> + <description class="text-blurb" id="projectDesc"> + &project.start; + <label is="text-link" href="https://www.torproject.org/"> + &project.tpoLink; + </label>&project.end; </description> - <description class="text-blurb" id="contributeDesc" data-l10n-id="helpus"> - <label is="text-link" href="https://donate.mozilla.org/?utm_source=firefox&#38;utm_medium=referral&#38;…" data-l10n-name="helpus-donateLink"/> - <label is="text-link" href="https://www.mozilla.org/contribute/?utm_source=firefox-browser&#38;utm_medi…" data-l10n-name="helpus-getInvolvedLink"/> + <description class="text-blurb" id="helpDesc"> + &help.start; + <label is="text-link" href="https://donate.torproject.org/"> + &help.donateLink; + </label> + &help.or; + <label is="text-link" href="https://community.torproject.org/"> + &help.getInvolvedLink; + </label>&help.end; </description> </vbox> </vbox> </hbox> <vbox id="bottomBox"> - <hbox pack="center"> - <label is="text-link" class="bottom-link" useoriginprincipal="true" href="about:license" data-l10n-id="bottomLinks-license"/> - <label is="text-link" class="bottom-link" useoriginprincipal="true" href="about:rights" data-l10n-id="bottomLinks-rights"/> - <label is="text-link" class="bottom-link" href="https://www.mozilla.org/privacy/?utm_source=firefox-browser&#38;utm_medium=…" data-l10n-id="bottomLinks-privacy"/> + <hbox id="newBottom" pack="center" position="1"> + <label is="text-link" class="bottom-link" href="https://support.torproject.org/">&bottomLinks.questions;</label> + <label is="text-link" class="bottom-link" href="https://community.torproject.org/relay/">&bottomLinks.grow;</label> + <label is="text-link" class="bottom-link" useoriginprincipal="true" href="about:license">&bottomLinks.license;</label> </hbox> <description id="trademark" data-l10n-id="trademarkInfo"></description> + <description id="trademarkTor">&tor.TrademarkStatement;</description> </vbox> </vbox> diff --git a/browser/base/content/browser-doctype.inc b/browser/base/content/browser-doctype.inc index db2242afacfd..ef5a370ac8c6 100644 --- a/browser/base/content/browser-doctype.inc +++ b/browser/base/content/browser-doctype.inc @@ -12,3 +12,9 @@ %syncBrandDTD; <!ENTITY % brandingsDTD SYSTEM "chrome://browser/locale/brandings.dtd"> %brandingsDTD; +<!ENTITY % torbuttonDTD SYSTEM "chrome://torbutton/locale/torbutton.dtd"> +%torbuttonDTD; +<!ENTITY % aboutTorDTD SYSTEM "chrome://torbutton/locale/aboutTor.dtd"> +%aboutTorDTD; +<!ENTITY % aboutDialogDTD SYSTEM "chrome://torbutton/locale/aboutDialog.dtd"> +%aboutDialogDTD; diff --git a/browser/base/content/browser-menubar.inc b/browser/base/content/browser-menubar.inc index 058c1e5835e0..1875e803e177 100644 --- a/browser/base/content/browser-menubar.inc +++ b/browser/base/content/browser-menubar.inc @@ -34,6 +34,18 @@ command="Tools:NonFissionWindow" accesskey="s" label="New Non-Fission Window"/> #endif + <menuseparator/> + <menuitem id="menu_newIdentity" + accesskey="&torbutton.context_menu.new_identity_key;" + key="torbutton-new-identity-key" + label="&torbutton.context_menu.new_identity;" + oncommand="torbutton_new_identity();"/> + <menuitem id="menu_newCircuit" + accesskey="&torbutton.context_menu.new_circuit_key;" + key="torbutton-new-circuit-key" + label="&torbutton.context_menu.new_circuit;" + oncommand="torbutton_new_circuit();"/> + <menuseparator/> <menuitem id="menu_openLocation" hidden="true" command="Browser:OpenLocation" @@ -455,21 +467,39 @@ <menupopup id="menu_HelpPopup" onpopupshowing="buildHelpMenu();"> <!-- Note: Items under here are cloned to the AppMenu Help submenu. The cloned items have their strings defined by appmenu-data-l10n-id. --> - <menuitem id="menu_openHelp" +#ifdef MOZ_UPDATER + <menuitem id="checkForUpdates" + data-l10n-id="menu-help-check-for-update" + appmenu-data-l10n-id="appmenu-help-check-for-update" + class="menuitem-iconic" + oncommand="openAboutDialog();"/> +#endif + <!-- dummy elements to avoid 'getElementById' errors --> + <box id="feedbackPage"/> + <box id="helpSafeMode"/> + <box id="menu_HelpPopup_reportPhishingtoolmenu"/> + <box id="menu_HelpPopup_reportPhishingErrortoolmenu"/> + <!-- Add Tor Browser manual link --> + <menuitem id="torBrowserUserManual" + oncommand="gBrowser.selectedTab = gBrowser.addTab('https://tb-manual.torproject.org/' + Services.locale.requestedLocale, {triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()});" + label="&aboutTor.torbrowser_user_manual.label;" + accesskey="&aboutTor.torbrowser_user_manual.accesskey;"/> + <!-- Bug 18905: Hide unused help menu items --> + <!-- <menuitem id="menu_openHelp" oncommand="openHelpLink('firefox-help')" onclick="checkForMiddleClick(this, event);" data-l10n-id="menu-get-help" appmenu-data-l10n-id="appmenu-get-help" #ifdef XP_MACOSX - key="key_openHelpMac"/> + key="key_openHelpMac"/> --> #else - /> + /> --> #endif - <menuitem id="feedbackPage" + <!-- <menuitem id="feedbackPage" oncommand="openFeedbackPage()" onclick="checkForMiddleClick(this, event);" data-l10n-id="menu-help-feedback-page" - appmenu-data-l10n-id="appmenu-help-feedback-page"/> + appmenu-data-l10n-id="appmenu-help-feedback-page"/> --> <menuitem id="troubleShooting" oncommand="openTroubleshootingPage()" onclick="checkForMiddleClick(this, event);" @@ -485,19 +515,20 @@ data-l10n-id="menu-help-taskmanager" appmenu-data-l10n-id="appmenu-help-taskmanager"/> <menuitem id="menu_HelpPopup_reportPhishingtoolmenu" + <!-- <menuitem id="menu_HelpPopup_reportPhishingtoolmenu" disabled="true" oncommand="openUILink(gSafeBrowsing.getReportURL('Phish'), event, {triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({})});" onclick="checkForMiddleClick(this, event);" hidden="true" data-l10n-id="menu-help-report-deceptive-site" - appmenu-data-l10n-id="appmenu-help-report-deceptive-site"/> - <menuitem id="menu_HelpPopup_reportPhishingErrortoolmenu" + appmenu-data-l10n-id="appmenu-help-report-deceptive-site"/> --> + <!-- <menuitem id="menu_HelpPopup_reportPhishingErrortoolmenu" disabled="true" oncommand="ReportFalseDeceptiveSite();" onclick="checkForMiddleClick(this, event);" data-l10n-id="menu-help-not-deceptive" appmenu-data-l10n-id="appmenu-help-not-deceptive" - hidden="true"/> + hidden="true"/> --> <menuseparator id="aboutSeparator"/> <menuitem id="aboutName" oncommand="openAboutDialog();" diff --git a/browser/base/content/browser-sets.inc b/browser/base/content/browser-sets.inc index 54d988951e43..58692aa0032d 100644 --- a/browser/base/content/browser-sets.inc +++ b/browser/base/content/browser-sets.inc @@ -385,4 +385,6 @@ data-l10n-id="hide-other-apps-shortcut" modifiers="accel,alt"/> #endif + <key id="torbutton-new-identity-key" modifiers="accel shift" key="U" oncommand="torbutton_new_identity()"/> + <key id="torbutton-new-circuit-key" modifiers="accel shift" key="L" oncommand="torbutton_new_circuit()"/> </keyset> diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 13b3b933e952..7e030dc329ee 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -666,6 +666,7 @@ var gPageIcons = { }; var gInitialPages = [ + "about:tor", "about:blank", "about:newtab", "about:home", diff --git a/browser/base/content/browser.xhtml b/browser/base/content/browser.xhtml index 0a1090292f54..4efdd79541a3 100644 --- a/browser/base/content/browser.xhtml +++ b/browser/base/content/browser.xhtml @@ -29,6 +29,8 @@ <?xml-stylesheet href="chrome://browser/skin/searchbar.css" type="text/css"?> <?xml-stylesheet href="chrome://browser/skin/places/tree-icons.css" type="text/css"?> <?xml-stylesheet href="chrome://browser/skin/places/editBookmark.css" type="text/css"?> +<?xml-stylesheet href="chrome://torbutton/skin/tor-circuit-display.css" type="text/css"?> +<?xml-stylesheet href="chrome://torbutton/skin/torbutton.css" type="text/css"?> # All DTD information is stored in a separate file so that it can be shared by # hiddenWindowMac.xhtml. @@ -105,11 +107,18 @@ Services.scriptloader.loadSubScript("chrome://browser/content/places/places-menupopup.js", this); Services.scriptloader.loadSubScript("chrome://browser/content/search/autocomplete-popup.js", this); Services.scriptloader.loadSubScript("chrome://browser/content/search/searchbar.js", this); + Services.scriptloader.loadSubScript("chrome://torbutton/content/tor-circuit-display.js", this); + Services.scriptloader.loadSubScript("chrome://torbutton/content/torbutton.js", this); window.onload = gBrowserInit.onLoad.bind(gBrowserInit); window.onunload = gBrowserInit.onUnload.bind(gBrowserInit); window.onclose = WindowIsClosing; + //onLoad Handler + try { + window.addEventListener("load", torbutton_init, false); + } catch (e) {} + window.addEventListener("MozBeforeInitialXULLayout", gBrowserInit.onBeforeInitialXULLayout.bind(gBrowserInit), { once: true }); @@ -784,7 +793,8 @@ class="subviewbutton subviewbutton-iconic" label="&newPrivateWindow.label;" key="key_privatebrowsing" - command="Tools:PrivateBrowsing"/> + command="Tools:PrivateBrowsing" + hidden="true"/> #ifdef NIGHTLY_BUILD <toolbarbutton id="appMenu-fission-window-button" class="subviewbutton subviewbutton-iconic" @@ -800,7 +810,19 @@ <toolbarbutton id="appMenuRestoreLastSession" label="&appMenuHistory.restoreSession.label;" class="subviewbutton subviewbutton-iconic" - command="Browser:RestoreLastSession"/> + command="Browser:RestoreLastSession" + hidden="true"/> + <toolbarseparator/> + <toolbarbutton id="appMenuNewIdentity" + class="subviewbutton subviewbutton-iconic" + key="torbutton-new-identity-key" + label="&torbutton.context_menu.new_identity;" + oncommand="torbutton_new_identity();"/> + <toolbarbutton id="appMenuNewCircuit" + class="subviewbutton subviewbutton-iconic" + key="torbutton-new-circuit-key" + label="&torbutton.context_menu.new_circuit;" + oncommand="torbutton_new_circuit();"/> <toolbarseparator/> <toolbaritem id="appMenu-zoom-controls" class="toolbaritem-combined-buttons" closemenu="none"> <!-- Use a spacer, because panel sizing code gets confused when using CSS methods. --> diff --git a/browser/components/controlcenter/content/identityPanel.inc.xhtml b/browser/components/controlcenter/content/identityPanel.inc.xhtml index 4dd3a3d58fdd..f6be226e8df3 100644 --- a/browser/components/controlcenter/content/identityPanel.inc.xhtml +++ b/browser/components/controlcenter/content/identityPanel.inc.xhtml @@ -88,6 +88,50 @@ oncommand="gIdentityHandler.showSecuritySubView();"/> </hbox> + <!-- Circuit display section --> + <hbox id="circuit-display-container" class="identity-popup-section"> + <vbox id="circuit-display-content" flex="1" role="group" + aria-labelledby="circuit-display-headline"> + <hbox id="circuit-display-header" align="center"> + <label id="circuit-display-headline" + role="heading" aria-level="2">&torbutton.circuit_display.title;</label> + </hbox> + <html:ul id="circuit-display-nodes" dir="auto"/> + </vbox> + <vbox id="circuit-reload-content" flex="1"> + <html:button id="circuit-reload-button" + onclick="torbutton_new_circuit()">&torbutton.circuit_display.new_circuit;</html:button> + <hbox id="circuit-guard-note-container"/> + </vbox> + </hbox> + + <!-- Permissions Section --> + <hbox class="identity-popup-section" + when-connection="not-secure secure secure-ev secure-cert-user-overridden file extension cert-error-page https-only-error-page"> + <vbox id="identity-popup-permissions-content" flex="1" role="group" + aria-labelledby="identity-popup-permissions-headline"> + <hbox id="identity-popup-permissions-header" align="center"> + <label id="identity-popup-permissions-headline" + role="heading" aria-level="2" + data-l10n-id="identity-permissions"/> + </hbox> + <vbox id="identity-popup-permission-list"> + <vbox id="identity-popup-permission-list-default-anchor" class="identity-popup-permission-list-anchor"/> + <vbox class="identity-popup-permission-list-anchor" anchorfor="3rdPartyStorage"> + <vbox id="identity-popup-storage-access-permission-list-header"> + <hbox align="center" role="group"> + <image class="identity-popup-permission-icon storage-access-icon"/> + <label data-l10n-id="identity-permissions-storage-access-header" class="identity-popup-permission-header-label"/> + </hbox> + <description id="identity-popup-storage-access-permission-list-hint" data-l10n-id="identity-permissions-storage-access-hint"></description> + </vbox> + </vbox> + </vbox> + <description id="identity-popup-permission-reload-hint" data-l10n-id="identity-permissions-reload-hint"></description> + <description id="identity-popup-permission-empty-hint" data-l10n-id="identity-permissions-empty"></description> + </vbox> + </hbox> + <!-- Clear Site Data Button --> <vbox hidden="true" id="identity-popup-clear-sitedata-footer" diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index 30b88fc38277..37b44b37d9ce 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -260,6 +260,8 @@ @RESPATH@/browser/chrome/torlauncher/* @RESPATH@/browser/@PREF_DIR@/torlauncher-prefs.js #endif +@RESPATH@/chrome/torbutton.manifest +@RESPATH@/chrome/torbutton/* @RESPATH@/chrome/toolkit@JAREXT@ @RESPATH@/chrome/toolkit.manifest @RESPATH@/chrome/recording.manifest diff --git a/docshell/base/nsAboutRedirector.cpp b/docshell/base/nsAboutRedirector.cpp index de7771efd273..32d4cefc5323 100644 --- a/docshell/base/nsAboutRedirector.cpp +++ b/docshell/base/nsAboutRedirector.cpp @@ -155,7 +155,11 @@ static const RedirEntry kRedirMap[] = { {"crashcontent", "about:blank", nsIAboutModule::HIDE_FROM_ABOUTABOUT | nsIAboutModule::URI_CAN_LOAD_IN_CHILD | - nsIAboutModule::URI_MUST_LOAD_IN_CHILD}}; + nsIAboutModule::URI_MUST_LOAD_IN_CHILD}, + {"tor", "chrome://torbutton/content/aboutTor/aboutTor.xhtml", + nsIAboutModule::URI_MUST_LOAD_IN_CHILD | + nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | + nsIAboutModule::ALLOW_SCRIPT}}; static const int kRedirTotal = mozilla::ArrayLength(kRedirMap); NS_IMETHODIMP diff --git a/docshell/build/components.conf b/docshell/build/components.conf index 69151f083cff..a83920802a5d 100644 --- a/docshell/build/components.conf +++ b/docshell/build/components.conf @@ -29,6 +29,7 @@ about_pages = [ 'srcdoc', 'support', 'telemetry', + 'tor', 'url-classifier', 'webrtc', ] diff --git a/mobile/android/installer/package-manifest.in b/mobile/android/installer/package-manifest.in index c30f426c2129..8af288f1810a 100644 --- a/mobile/android/installer/package-manifest.in +++ b/mobile/android/installer/package-manifest.in @@ -132,6 +132,10 @@ @BINPATH@/chrome/devtools@JAREXT@ @BINPATH@/chrome/devtools.manifest +; Torbutton +@BINPATH@/chrome/torbutton@JAREXT@ +@BINPATH@/chrome/torbutton.manifest + ; [Default Preferences] ; All the pref files must be part of base to prevent migration bugs #ifndef MOZ_ANDROID_FAT_AAR_ARCHITECTURES diff --git a/toolkit/moz.build b/toolkit/moz.build index 14f4638b693e..4edccfac6d62 100644 --- a/toolkit/moz.build +++ b/toolkit/moz.build @@ -22,6 +22,7 @@ DIRS += [ "mozapps/preferences", "profile", "themes", + "torproject/torbutton", ] if CONFIG["OS_ARCH"] == "WINNT" and CONFIG["MOZ_DEFAULT_BROWSER_AGENT"]: diff --git a/toolkit/mozapps/extensions/internal/XPIProvider.jsm b/toolkit/mozapps/extensions/internal/XPIProvider.jsm index d1ed386fe676..4eec53e3b703 100644 --- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm +++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm @@ -1469,6 +1469,15 @@ var XPIStates = { for (let [id, file] of loc.readAddons()) { knownIds.delete(id); + // Uninstall torbutton if it is installed in the user profile + if (id === "torbutton(a)torproject.org" && + loc.name === KEY_APP_PROFILE) { + logger.debug("Uninstalling torbutton from user profile."); + loc.installer.uninstallAddon(id); + changed = true; + continue; + } + // Since it is now part of the browser, uninstall the Tor Launcher // extension. This will remove the Tor Launcher .xpi from user // profiles on macOS. diff --git a/toolkit/torproject/torbutton b/toolkit/torproject/torbutton new file mode 160000 index 000000000000..ba38a0f51e25 --- /dev/null +++ b/toolkit/torproject/torbutton @@ -0,0 +1 @@ +Subproject commit ba38a0f51e2556a896feb0baf1fb4fd7f3970c3b diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/environments/browser-window.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/environments/browser-window.js index 76e03f2d49bb..2ff107b553b2 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/environments/browser-window.js +++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/environments/browser-window.js @@ -75,7 +75,11 @@ function getGlobalScriptIncludes(scriptPath) { "browser/components/search/content/" ) .replace("chrome://browser/content/", "browser/base/content/") - .replace("chrome://global/content/", "toolkit/content/"); + .replace("chrome://global/content/", "toolkit/content/") + .replace( + "chrome://torbutton/content/", + "toolkit/torproject/torbutton/chrome/content/" + ); for (let mapping of Object.getOwnPropertyNames(MAPPINGS)) { if (sourceFile.includes(mapping)) {
1 0
0 0
[tor-browser/tor-browser-87.0b4-10.5-1] Bug 14631: Improve profile access error messages.
by sysrqb@torproject.org 11 Mar '21

11 Mar '21
commit 2f80ad677e3a03cae28bbf212bc5b8709917ef4c Author: Kathy Brade <brade(a)pearlcrescent.com> Date: Tue Feb 24 13:50:23 2015 -0500 Bug 14631: Improve profile access error messages. Instead of always reporting that the profile is locked, display specific messages for "access denied" and "read-only file system". To allow for localization, get profile-related error strings from Torbutton. Use app display name ("Tor Browser") in profile-related error alerts. --- .../mozapps/profile/profileSelection.properties | 5 + toolkit/profile/nsToolkitProfileService.cpp | 57 +++++++- toolkit/profile/nsToolkitProfileService.h | 13 +- toolkit/xre/nsAppRunner.cpp | 157 ++++++++++++++++++--- 4 files changed, 208 insertions(+), 24 deletions(-) diff --git a/toolkit/locales/en-US/chrome/mozapps/profile/profileSelection.properties b/toolkit/locales/en-US/chrome/mozapps/profile/profileSelection.properties index d326083202b2..aa38bda24347 100644 --- a/toolkit/locales/en-US/chrome/mozapps/profile/profileSelection.properties +++ b/toolkit/locales/en-US/chrome/mozapps/profile/profileSelection.properties @@ -12,6 +12,11 @@ restartMessageUnlocker=%S is already running, but is not responding. The old %S restartMessageNoUnlockerMac=A copy of %S is already open. Only one copy of %S can be open at a time. restartMessageUnlockerMac=A copy of %S is already open. The running copy of %S will quit in order to open this one. +# LOCALIZATION NOTE (profileProblemTitle, profileReadOnly, profileReadOnlyMac, profileAccessDenied): Messages displayed when the browser profile cannot be accessed or written to. %S is the application name. +profileProblemTitle=%S Profile Problem +profileReadOnly=You cannot run %S from a read-only file system. Please copy %S to another location before trying to use it. +profileReadOnlyMac=You cannot run %S from a read-only file system. Please copy %S to your Desktop or Applications folder before trying to use it. +profileAccessDenied=%S does not have permission to access the profile. Please adjust your file system permissions and try again. # Profile manager # LOCALIZATION NOTE (profileTooltip): First %S is the profile name, second %S is the path to the profile folder. profileTooltip=Profile: ‘%S’ — Path: ‘%S’ diff --git a/toolkit/profile/nsToolkitProfileService.cpp b/toolkit/profile/nsToolkitProfileService.cpp index 38592720785b..a17d22b8a1d4 100644 --- a/toolkit/profile/nsToolkitProfileService.cpp +++ b/toolkit/profile/nsToolkitProfileService.cpp @@ -1164,9 +1164,10 @@ nsToolkitProfileService::SelectStartupProfile( } bool wasDefault; + ProfileStatus profileStatus; nsresult rv = SelectStartupProfile(&argc, argv.get(), aIsResetting, aRootDir, aLocalDir, - aProfile, aDidCreate, &wasDefault); + aProfile, aDidCreate, &wasDefault, profileStatus); // Since we were called outside of the normal startup path complete any // startup tasks. @@ -1199,7 +1200,8 @@ nsToolkitProfileService::SelectStartupProfile( nsresult nsToolkitProfileService::SelectStartupProfile( int* aArgc, char* aArgv[], bool aIsResetting, nsIFile** aRootDir, nsIFile** aLocalDir, nsIToolkitProfile** aProfile, bool* aDidCreate, - bool* aWasDefaultSelection) { + bool* aWasDefaultSelection, ProfileStatus& aProfileStatus) { + aProfileStatus = PROFILE_STATUS_OK; if (mStartupProfileSelected) { return NS_ERROR_ALREADY_INITIALIZED; } @@ -1293,6 +1295,13 @@ nsresult nsToolkitProfileService::SelectStartupProfile( rv = XRE_GetFileFromPath(arg, getter_AddRefs(lf)); NS_ENSURE_SUCCESS(rv, rv); + aProfileStatus = CheckProfileWriteAccess(lf); + if (PROFILE_STATUS_OK != aProfileStatus) { + NS_ADDREF(*aRootDir = lf); + NS_ADDREF(*aLocalDir = lf); + return NS_ERROR_FAILURE; + } + // Make sure that the profile path exists and it's a directory. bool exists; rv = lf->Exists(&exists); @@ -2089,3 +2098,47 @@ nsresult XRE_GetFileFromPath(const char* aPath, nsIFile** aResult) { # error Platform-specific logic needed here. #endif } + +// Check for write permission to the profile directory by trying to create a +// new file (after ensuring that no file with the same name exists). +ProfileStatus nsToolkitProfileService::CheckProfileWriteAccess( + nsIFile* aProfileDir) { +#if defined(XP_UNIX) + constexpr auto writeTestFileName = u".parentwritetest"_ns; +#else + constexpr auto writeTestFileName = u"parent.writetest"_ns; +#endif + + nsCOMPtr<nsIFile> writeTestFile; + nsresult rv = aProfileDir->Clone(getter_AddRefs(writeTestFile)); + if (NS_SUCCEEDED(rv)) rv = writeTestFile->Append(writeTestFileName); + + if (NS_SUCCEEDED(rv)) { + bool doesExist = false; + rv = writeTestFile->Exists(&doesExist); + if (NS_SUCCEEDED(rv) && doesExist) rv = writeTestFile->Remove(true); + } + + if (NS_SUCCEEDED(rv)) { + rv = writeTestFile->Create(nsIFile::NORMAL_FILE_TYPE, 0666); + (void)writeTestFile->Remove(true); + } + + ProfileStatus status = + NS_SUCCEEDED(rv) ? PROFILE_STATUS_OK : PROFILE_STATUS_OTHER_ERROR; + if (NS_ERROR_FILE_ACCESS_DENIED == rv) + status = PROFILE_STATUS_ACCESS_DENIED; + else if (NS_ERROR_FILE_READ_ONLY == rv) + status = PROFILE_STATUS_READ_ONLY; + + return status; +} + +ProfileStatus nsToolkitProfileService::CheckProfileWriteAccess( + nsIToolkitProfile* aProfile) { + nsCOMPtr<nsIFile> profileDir; + nsresult rv = aProfile->GetRootDir(getter_AddRefs(profileDir)); + if (NS_FAILED(rv)) return PROFILE_STATUS_OTHER_ERROR; + + return CheckProfileWriteAccess(profileDir); +} diff --git a/toolkit/profile/nsToolkitProfileService.h b/toolkit/profile/nsToolkitProfileService.h index 6b68c019ca52..aa92b9a27b64 100644 --- a/toolkit/profile/nsToolkitProfileService.h +++ b/toolkit/profile/nsToolkitProfileService.h @@ -16,6 +16,14 @@ #include "nsProfileLock.h" #include "nsINIParser.h" +enum ProfileStatus { + PROFILE_STATUS_OK, + PROFILE_STATUS_ACCESS_DENIED, + PROFILE_STATUS_READ_ONLY, + PROFILE_STATUS_IS_LOCKED, + PROFILE_STATUS_OTHER_ERROR +}; + class nsToolkitProfile final : public nsIToolkitProfile, public mozilla::LinkedListElement<RefPtr<nsToolkitProfile>> { @@ -80,10 +88,13 @@ class nsToolkitProfileService final : public nsIToolkitProfileService { nsresult SelectStartupProfile(int* aArgc, char* aArgv[], bool aIsResetting, nsIFile** aRootDir, nsIFile** aLocalDir, nsIToolkitProfile** aProfile, bool* aDidCreate, - bool* aWasDefaultSelection); + bool* aWasDefaultSelection, + ProfileStatus& aProfileStatus); nsresult CreateResetProfile(nsIToolkitProfile** aNewProfile); nsresult ApplyResetProfile(nsIToolkitProfile* aOldProfile); void CompleteStartup(); + static ProfileStatus CheckProfileWriteAccess(nsIToolkitProfile* aProfile); + static ProfileStatus CheckProfileWriteAccess(nsIFile* aProfileDir); private: friend class nsToolkitProfile; diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index d894ed34f291..904c89f7fb4b 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -2254,6 +2254,91 @@ nsresult LaunchChild(bool aBlankCommandLine, bool aTryExec) { return NS_ERROR_LAUNCHED_CHILD_PROCESS; } +static nsresult GetOverrideStringBundleForLocale(nsIStringBundleService* aSBS, + const char* aTorbuttonURI, + const char* aLocale, + nsIStringBundle** aResult) { + NS_ENSURE_ARG(aSBS); + NS_ENSURE_ARG(aTorbuttonURI); + NS_ENSURE_ARG(aLocale); + NS_ENSURE_ARG(aResult); + + const char* kFormatStr = + "jar:%s!/chrome/torbutton/locale/%s/torbutton.properties"; + nsPrintfCString strBundleURL(kFormatStr, aTorbuttonURI, aLocale); + nsresult rv = aSBS->CreateBundle(strBundleURL.get(), aResult); + NS_ENSURE_SUCCESS(rv, rv); + + // To ensure that we have a valid string bundle, try to retrieve a string + // that we know exists. + nsAutoString val; + rv = (*aResult)->GetStringFromName("profileProblemTitle", val); + if (!NS_SUCCEEDED(rv)) *aResult = nullptr; // No good. Discard it. + + return rv; +} + +static void GetOverrideStringBundle(nsIStringBundleService* aSBS, + nsIStringBundle** aResult) { + if (!aSBS || !aResult) return; + + *aResult = nullptr; + + // Build Torbutton file URI string by starting from GREDir. + RefPtr<nsXREDirProvider> dirProvider = nsXREDirProvider::GetSingleton(); + if (!dirProvider) return; + + nsCOMPtr<nsIFile> greDir = dirProvider->GetGREDir(); + if (!greDir) return; + + // Create file URI, extract as string, and append omni.ja relative path. + nsCOMPtr<nsIURI> uri; + nsAutoCString uriString; + if (NS_FAILED(NS_NewFileURI(getter_AddRefs(uri), greDir)) || + NS_FAILED(uri->GetSpec(uriString))) { + return; + } + + uriString.Append("omni.ja"); + + nsAutoCString userAgentLocale; + if (!NS_SUCCEEDED( + Preferences::GetCString("intl.locale.requested", userAgentLocale))) { + return; + } + + nsresult rv = GetOverrideStringBundleForLocale( + aSBS, uriString.get(), userAgentLocale.get(), aResult); + if (NS_FAILED(rv)) { + // Try again using base locale, e.g., "en" vs. "en-US". + int16_t offset = userAgentLocale.FindChar('-', 1); + if (offset > 0) { + nsAutoCString shortLocale(Substring(userAgentLocale, 0, offset)); + rv = GetOverrideStringBundleForLocale(aSBS, uriString.get(), + shortLocale.get(), aResult); + } + } +} + +static nsresult GetFormattedString(nsIStringBundle* aOverrideBundle, + nsIStringBundle* aMainBundle, + const char* aName, + const nsTArray<nsString>& aParams, + nsAString& aResult) { + NS_ENSURE_ARG(aName); + + nsresult rv = NS_ERROR_FAILURE; + if (aOverrideBundle) { + rv = aOverrideBundle->FormatStringFromName(aName, aParams, aResult); + } + + // If string was not found in override bundle, use main (browser) bundle. + if (NS_FAILED(rv) && aMainBundle) + rv = aMainBundle->FormatStringFromName(aName, aParams, aResult); + + return rv; +} + static const char kProfileProperties[] = "chrome://mozapps/locale/profile/profileSelection.properties"; @@ -2311,7 +2396,7 @@ static nsresult ProfileMissingDialog(nsINativeAppSupport* aNative) { sbs->CreateBundle(kProfileProperties, getter_AddRefs(sb)); NS_ENSURE_TRUE_LOG(sbs, NS_ERROR_FAILURE); - NS_ConvertUTF8toUTF16 appName(gAppData->name); + NS_ConvertUTF8toUTF16 appName(MOZ_APP_DISPLAYNAME); AutoTArray<nsString, 2> params = {appName, appName}; // profileMissing @@ -2333,11 +2418,12 @@ static nsresult ProfileMissingDialog(nsINativeAppSupport* aNative) { } } -static ReturnAbortOnError ProfileLockedDialog(nsIFile* aProfileDir, - nsIFile* aProfileLocalDir, - nsIProfileUnlocker* aUnlocker, - nsINativeAppSupport* aNative, - nsIProfileLock** aResult) { +static ReturnAbortOnError ProfileErrorDialog(nsIFile* aProfileDir, + nsIFile* aProfileLocalDir, + ProfileStatus aStatus, + nsIProfileUnlocker* aUnlocker, + nsINativeAppSupport* aNative, + nsIProfileLock** aResult) { nsresult rv; bool exists; @@ -2365,24 +2451,39 @@ static ReturnAbortOnError ProfileLockedDialog(nsIFile* aProfileDir, sbs->CreateBundle(kProfileProperties, getter_AddRefs(sb)); NS_ENSURE_TRUE_LOG(sbs, NS_ERROR_FAILURE); - NS_ConvertUTF8toUTF16 appName(gAppData->name); + nsCOMPtr<nsIStringBundle> overrideSB; + GetOverrideStringBundle(sbs, getter_AddRefs(overrideSB)); + + NS_ConvertUTF8toUTF16 appName(MOZ_APP_DISPLAYNAME); AutoTArray<nsString, 3> params = {appName, appName, appName}; nsAutoString killMessage; #ifndef XP_MACOSX - rv = sb->FormatStringFromName( - aUnlocker ? "restartMessageUnlocker" : "restartMessageNoUnlocker2", - params, killMessage); + static const char kRestartUnlocker[] = "restartMessageUnlocker"; + static const char kRestartNoUnlocker[] = "restartMessageNoUnlocker2"; + static const char kReadOnly[] = "profileReadOnly"; #else - rv = sb->FormatStringFromName( - aUnlocker ? "restartMessageUnlockerMac" : "restartMessageNoUnlockerMac", - params, killMessage); -#endif + static const char kRestartUnlocker[] = "restartMessageUnlockerMac"; + static const char kRestartNoUnlocker[] = "restartMessageNoUnlockerMac"; + static const char kReadOnly[] = "profileReadOnlyMac"; +#endif + static const char kAccessDenied[] = "profileAccessDenied"; + + const char* errorKey = aUnlocker ? kRestartUnlocker : kRestartNoUnlocker; + if (PROFILE_STATUS_READ_ONLY == aStatus) + errorKey = kReadOnly; + else if (PROFILE_STATUS_ACCESS_DENIED == aStatus) + errorKey = kAccessDenied; + rv = GetFormattedString(overrideSB, sb, errorKey, params, killMessage); NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); + const char* titleKey = ((PROFILE_STATUS_READ_ONLY == aStatus) || + (PROFILE_STATUS_ACCESS_DENIED == aStatus)) + ? "profileProblemTitle" + : "restartTitle"; params.SetLength(1); nsAutoString killTitle; - rv = sb->FormatStringFromName("restartTitle", params, killTitle); + rv = sb->FormatStringFromName(titleKey, params, killTitle); NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); if (gfxPlatform::IsHeadless()) { @@ -2541,6 +2642,13 @@ static nsCOMPtr<nsIToolkitProfile> gResetOldProfile; static nsresult LockProfile(nsINativeAppSupport* aNative, nsIFile* aRootDir, nsIFile* aLocalDir, nsIToolkitProfile* aProfile, nsIProfileLock** aResult) { + ProfileStatus status = + (aProfile ? nsToolkitProfileService::CheckProfileWriteAccess(aProfile) + : nsToolkitProfileService::CheckProfileWriteAccess(aRootDir)); + if (PROFILE_STATUS_OK != status) + return ProfileErrorDialog(aRootDir, aLocalDir, status, nullptr, aNative, + aResult); + // If you close Firefox and very quickly reopen it, the old Firefox may // still be closing down. Rather than immediately showing the // "Firefox is running but is not responding" message, we spend a few @@ -2567,7 +2675,8 @@ static nsresult LockProfile(nsINativeAppSupport* aNative, nsIFile* aRootDir, } while (TimeStamp::Now() - start < TimeDuration::FromSeconds(kLockRetrySeconds)); - return ProfileLockedDialog(aRootDir, aLocalDir, unlocker, aNative, aResult); + return ProfileErrorDialog(aRootDir, aLocalDir, PROFILE_STATUS_IS_LOCKED, + unlocker, aNative, aResult); } // Pick a profile. We need to end up with a profile root dir, local dir and @@ -2582,7 +2691,8 @@ static nsresult LockProfile(nsINativeAppSupport* aNative, nsIFile* aRootDir, static nsresult SelectProfile(nsToolkitProfileService* aProfileSvc, nsINativeAppSupport* aNative, nsIFile** aRootDir, nsIFile** aLocalDir, nsIToolkitProfile** aProfile, - bool* aWasDefaultSelection) { + bool* aWasDefaultSelection, + nsIProfileLock** aResult) { StartupTimeline::Record(StartupTimeline::SELECT_PROFILE); nsresult rv; @@ -2628,9 +2738,14 @@ static nsresult SelectProfile(nsToolkitProfileService* aProfileSvc, // Ask the profile manager to select the profile directories to use. bool didCreate = false; - rv = aProfileSvc->SelectStartupProfile(&gArgc, gArgv, gDoProfileReset, - aRootDir, aLocalDir, aProfile, - &didCreate, aWasDefaultSelection); + ProfileStatus profileStatus = PROFILE_STATUS_OK; + rv = aProfileSvc->SelectStartupProfile( + &gArgc, gArgv, gDoProfileReset, aRootDir, aLocalDir, aProfile, &didCreate, + aWasDefaultSelection, profileStatus); + if (PROFILE_STATUS_OK != profileStatus) { + return ProfileErrorDialog(*aRootDir, *aLocalDir, profileStatus, nullptr, + aNative, aResult); + } if (rv == NS_ERROR_SHOW_PROFILE_MANAGER) { return ShowProfileManager(aProfileSvc, aNative); @@ -4452,7 +4567,7 @@ int XREMain::XRE_mainStartup(bool* aExitFlag) { nsCOMPtr<nsIToolkitProfile> profile; rv = SelectProfile(mProfileSvc, mNativeApp, getter_AddRefs(mProfD), getter_AddRefs(mProfLD), getter_AddRefs(profile), - &wasDefaultSelection); + &wasDefaultSelection, getter_AddRefs(mProfileLock)); if (rv == NS_ERROR_LAUNCHED_CHILD_PROCESS || rv == NS_ERROR_ABORT) { *aExitFlag = true; return 0;
1 0
0 0
[tor-browser/tor-browser-87.0b4-10.5-1] Bug 16620: Clear window.name when no referrer sent
by sysrqb@torproject.org 11 Mar '21

11 Mar '21
commit 7142737a392c8274d54abdec88c1364737988653 Author: Kathy Brade <brade(a)pearlcrescent.com> Date: Fri Oct 30 14:28:13 2015 -0400 Bug 16620: Clear window.name when no referrer sent Convert JS implementation (within Torbutton) to a C++ browser patch. --- docshell/base/nsDocShell.cpp | 60 +++++++ docshell/test/mochitest/mochitest.ini | 3 + docshell/test/mochitest/test_tor_bug16620.html | 211 +++++++++++++++++++++++++ docshell/test/mochitest/tor_bug16620.html | 51 ++++++ docshell/test/mochitest/tor_bug16620_form.html | 51 ++++++ modules/libpref/init/StaticPrefList.yaml | 2 +- 6 files changed, 377 insertions(+), 1 deletion(-) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index ceedd4c317b8..a78bdbadf84b 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -7883,11 +7883,71 @@ nsresult nsDocShell::CreateContentViewer(const nsACString& aContentType, aOpenedChannel->GetURI(getter_AddRefs(mLoadingURI)); } FirePageHideNotification(!mSavingOldViewer); + if (mIsBeingDestroyed) { // Force to stop the newly created orphaned viewer. viewer->Stop(); return NS_ERROR_DOCSHELL_DYING; } + + // Tor bug 16620: Clear window.name of top-level documents if + // there is no referrer. We make an exception for new windows, + // e.g., window.open(url, "MyName"). + bool isNewWindowTarget = false; + nsCOMPtr<nsIPropertyBag2> props(do_QueryInterface(aRequest, &rv)); + if (props) { + props->GetPropertyAsBool(u"docshell.newWindowTarget"_ns, + &isNewWindowTarget); + } + + if (!isNewWindowTarget) { + nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(aOpenedChannel)); + nsCOMPtr<nsIURI> httpReferrer; + if (httpChannel) { + nsCOMPtr<nsIReferrerInfo> referrerInfo; + rv = httpChannel->GetReferrerInfo(getter_AddRefs(referrerInfo)); + NS_ENSURE_SUCCESS(rv, rv); + if (referrerInfo) { + // We want GetComputedReferrer() instead of GetOriginalReferrer(), since + // the former takes into consideration referrer policy, protocol + // whitelisting... + httpReferrer = referrerInfo->GetComputedReferrer(); + } + } + + bool isTopFrame = mBrowsingContext->IsTop(); + +#ifdef DEBUG_WINDOW_NAME + printf("DOCSHELL %p CreateContentViewer - possibly clearing window.name:\n", + this); + printf(" current window.name: \"%s\"\n", + NS_ConvertUTF16toUTF8(mName).get()); + + nsAutoCString curSpec, loadingSpec; + if (this->mCurrentURI) mCurrentURI->GetSpec(curSpec); + if (mLoadingURI) mLoadingURI->GetSpec(loadingSpec); + printf(" current URI: %s\n", curSpec.get()); + printf(" loading URI: %s\n", loadingSpec.get()); + printf(" is top document: %s\n", isTopFrame ? "Yes" : "No"); + + if (!httpReferrer) { + printf(" referrer: None\n"); + } else { + nsAutoCString refSpec; + httpReferrer->GetSpec(refSpec); + printf(" referrer: %s\n", refSpec.get()); + } +#endif + + bool clearName = isTopFrame && !httpReferrer; + if (clearName) SetName(u""_ns); + +#ifdef DEBUG_WINDOW_NAME + printf(" action taken: %s window.name\n", + clearName ? "Cleared" : "Preserved"); +#endif + } + mLoadingURI = nullptr; // Set mFiredUnloadEvent = false so that the unload handler for the diff --git a/docshell/test/mochitest/mochitest.ini b/docshell/test/mochitest/mochitest.ini index 544060110c77..6f4e16f18ef8 100644 --- a/docshell/test/mochitest/mochitest.ini +++ b/docshell/test/mochitest/mochitest.ini @@ -53,6 +53,8 @@ support-files = start_historyframe.html url1_historyframe.html url2_historyframe.html + tor_bug16620.html + tor_bug16620_form.html prefs = gfx.font_rendering.fallback.async=false @@ -130,6 +132,7 @@ support-files = file_history_length_during_pageload.html file_history_length_during_pageload_2.html [test_pushState_after_document_open.html] +[test_tor_bug16620.html] [test_navigate_after_pagehide.html] [test_redirect_history.html] support-files = diff --git a/docshell/test/mochitest/test_tor_bug16620.html b/docshell/test/mochitest/test_tor_bug16620.html new file mode 100644 index 000000000000..46fff5a04711 --- /dev/null +++ b/docshell/test/mochitest/test_tor_bug16620.html @@ -0,0 +1,211 @@ +<!DOCTYPE HTML> +<html> +<!-- + Tor Bug 16620: Clear window.name when no referrer sent. + https://trac.torproject.org/projects/tor/ticket/16620 +--> +<meta charset="utf-8"> +<head> + <title>Test for Tor Bug 16620 - Clear window.name when no referrer sent</title> + <script type="application/javascript" + src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://trac.torproject.org/projects/tor/ticket/16620">Tor Bug 16620</a> +<script> +// ## Test constants +const kTestPath = "/tests/docshell/test/mochitest/"; +const kLinkFile = "tor_bug16620.html"; +const kFormFile = "tor_bug16620_form.html"; +const kBaseURL1 = "http://example.com"; +const kBaseURL1_https = "https://example.com"; +const kBaseURL2 = "http://example.net"; +const kSendReferrerPref = "network.http.sendRefererHeader"; +const kSendReferrerNever = 0; +const kSendReferrerForUserAction = 1; +const kSendReferrerAlways = 2; + +let gTests = [ + // Test #1: Same domain; never send referrer. + { startURL: kBaseURL1, destURL: kBaseURL1, + referrerPref: kSendReferrerNever, + expectIsolation: true }, + + // Test #2: Same domain; send referrer upon user action. + { startURL: kBaseURL1, destURL: kBaseURL1, + referrerPref: kSendReferrerForUserAction, + expectIsolation: false }, + + // Test #3: Same domain; always send referrer. + { startURL: kBaseURL1, destURL: kBaseURL1, + referrerPref: kSendReferrerAlways, + expectIsolation: false }, + + // Test #4: Different top-level domains; never send referrer. + { startURL: kBaseURL1, destURL: kBaseURL2, + referrerPref: kSendReferrerNever, + expectIsolation: true }, + + // Test #5: Different top-level domains; send referrer upon user action. + { startURL: kBaseURL1, destURL: kBaseURL2, + referrerPref: kSendReferrerForUserAction, + expectIsolation: false }, + + // Test #6: Different top-level domains; always send referrer. + { startURL: kBaseURL1, destURL: kBaseURL2, + referrerPref: kSendReferrerAlways, + expectIsolation: false }, + + // Test #7: https -> http transition. + { startURL: kBaseURL1_https, destURL: kBaseURL1, + referrerPref: kSendReferrerForUserAction, + expectIsolation: true }, + + // Test #8: Same domain, rel="noreferrer" on link. + { startURL: kBaseURL1, destURL: kBaseURL1, noReferrerOnLink: true, + referrerPref: kSendReferrerAlways, + expectIsolation: true }, + + // Test #9: Same domain, "no-referrer" meta tag in document. + { startURL: kBaseURL1, destURL: kBaseURL1, noReferrerInMetaTag: true, + referrerPref: kSendReferrerAlways, + expectIsolation: true }, + + // Test #10: Like test #9, but reset window.name during unload. + // (similar to http://www.thomasfrank.se/sessvarsTestPage1.html) + { startURL: kBaseURL1, destURL: kBaseURL1, noReferrerInMetaTag: true, + resetInUnload: true, + referrerPref: kSendReferrerAlways, + expectIsolation: true }, + + // Test #11: Data URL as destination (no referrer). + { startURL: kBaseURL1, + referrerPref: kSendReferrerAlways, + expectIsolation: true }, + + // Test #12: Ensure that window.name is preserved when a dynamically loaded + // iframe is used to perform a form post (regression test for Tor bug 18168). + { startURL: kBaseURL1, + isFormTest: true, + referrerPref: kSendReferrerAlways, + expectIsolation: false }, +]; + +let gCurTest = 0; +let gCurWinName, gChildWin, gDataURL; + +// ## Utility functions +function generateRandomName() +{ + // Generate a random 6 character string using 0-9 and a-z. + return ((1 + Math.random()).toString(36) + '000000').substr(2, 6); +} + +function startNextTest() { + ++gCurTest; + if (gCurTest > gTests.length) { + SimpleTest.finish(); + } else { + let curTest = gTests[gCurTest - 1]; + if ("referrerPref" in curTest) + SpecialPowers.setIntPref(kSendReferrerPref, curTest.referrerPref); + else + SpecialPowers.setIntPref(kSendReferrerPref, kSendReferrerForUserAction); + gCurWinName = generateRandomName(); + let url = curTest.startURL + kTestPath; + if (curTest.isFormTest === true) { + url += kFormFile + "?" + gCurWinName; + gChildWin = window.open(url, undefined); + } else { + url += kLinkFile + "?firstDocLoaded"; + gChildWin = window.open(url, gCurWinName); + } + } +} + +// ## Add a message event listener. +window.addEventListener("message", function(aEvent) { + if (aEvent.source !== gChildWin) + return; + +// console.log("parent received message:" + JSON.stringify(aEvent.data)); + + let proceedToNextTest = false; + let curTest = gTests[gCurTest - 1]; + let state = aEvent.data.state; + let winName = aEvent.data.winName; + if ("firstDocLoaded" == state) { + // Process response from step one of the link-based tests. + let step1Passed = (winName === gCurWinName); + if (!step1Passed) { + ok(step1Passed, "Test #" + gCurTest + + " - first document's name matches window.open parameter"); + proceedToNextTest = true; + } + + // Send an "openURL" message to the loaded document. + let url2 = (curTest.destURL) + ? curTest.destURL + kTestPath + kLinkFile + "?secondDocLoaded" + : gDataURL; + let noReferrerOnLink = (curTest.noReferrerOnLink === true); + let noReferrerInMetaTag = (curTest.noReferrerInMetaTag === true); + let resetInUnload = (curTest.resetInUnload === true); + aEvent.source.postMessage({ action: "openURL", url: url2, + noReferrerOnLink: noReferrerOnLink, + noReferrerInMetaTag: noReferrerInMetaTag, + resetInUnload: resetInUnload }, + "*"); + } else if ("secondDocLoaded" == state) { + // Process response from step two of the link-based tests. + if (curTest.expectIsolation) { + ok(winName === "", + "Test #" + gCurTest + " - second document: name was cleared"); + } else { + ok(winName === gCurWinName, + "Test #" + gCurTest + " - second document: name was preserved"); + } + proceedToNextTest = true; + } else if ("formPostDone" == state) { + // Process response from the form post tests. + if (curTest.expectIsolation) { + ok(winName === "", + "Test #" + gCurTest + " - iframe form post: name was cleared"); + } else { + ok(winName === gCurWinName, + "Test #" + gCurTest + " - iframe form post: name was preserved"); + } + proceedToNextTest = true; + + } + + if (proceedToNextTest) { + gChildWin.close(); + startNextTest(); + } + }, false); + + SimpleTest.waitForExplicitFinish(); + + if (SpecialPowers.getBoolPref("security.nocertdb")) { + // Mochitests don't simulate https correctly with "security.nocertdb" + // enabled. See https://bugs.torproject.org/18087 + ok(false, "Please disable the pref `security.nocertdb` before running this test."); + SimpleTest.finish(); + } else { + + // Read file contents, construct a data URL (used by some tests), and + // then start the first test. + let url = kTestPath + kLinkFile; + let xhr = new XMLHttpRequest(); + xhr.open("GET", url); + xhr.onload = function() { + gDataURL = "data:text/html;charset=utf-8," + + encodeURIComponent(this.responseText); + startNextTest(); + } + xhr.send(); + } +</script> +</body> +</html> diff --git a/docshell/test/mochitest/tor_bug16620.html b/docshell/test/mochitest/tor_bug16620.html new file mode 100644 index 000000000000..26b8e406bbff --- /dev/null +++ b/docshell/test/mochitest/tor_bug16620.html @@ -0,0 +1,51 @@ +<!DOCTYPE HTML> +<html> +<!-- + Tor Bug 16620: Clear window.name when no referrer sent. + https://trac.torproject.org/projects/tor/ticket/16620 +--> +<head> + <meta charset="UTF-8"> + <title>Supporting Doc for Tor Bug 16620 Tests</title> +</head> +<body> +<a id="link" href="">secondDoc</a> + +<script> +// Extract test state from our query string, defaulting to +// "secondDocLoaded" to support use of this HTML content within +// a data URI (where query strings are not supported). +let state = (location.search.length > 0) ? location.search.substr(1) + : "secondDocLoaded"; + +// Notify the test driver. +opener.postMessage({ state: state, winName: window.name }, "*"); + +// Add a message event listener to process "openURL" actions. +window.addEventListener("message", function(aEvent) { + if (aEvent.data.action == "openURL") { + if (aEvent.data.noReferrerInMetaTag) { + let metaElem = document.createElement("meta"); + metaElem.name = "referrer"; + metaElem.content = "no-referrer"; + document.head.appendChild(metaElem); + } + + let linkElem = document.getElementById("link"); + linkElem.href = aEvent.data.url; + if (aEvent.data.noReferrerOnLink) + linkElem.rel = "noreferrer"; + + if (aEvent.data.resetInUnload) { + let tmpName = window.name; + window.addEventListener("unload", function() { + window.name = tmpName; + }, false); + } + + linkElem.click(); + } +}, false); +</script> +</body> +</html> diff --git a/docshell/test/mochitest/tor_bug16620_form.html b/docshell/test/mochitest/tor_bug16620_form.html new file mode 100644 index 000000000000..279f62e63fab --- /dev/null +++ b/docshell/test/mochitest/tor_bug16620_form.html @@ -0,0 +1,51 @@ +<!DOCTYPE HTML> +<html> +<!-- + Tor Bug 16620: Clear window.name when no referrer sent. + https://trac.torproject.org/projects/tor/ticket/16620 + + Regression test for bug 18168: iframe-based AJAX call opening in new tab +--> +<head> + <meta charset="UTF-8"> + <title>Supporting Form-based Doc for Tor Bug 16620 Tests</title> +</head> +<body> + +<script> +document.addEventListener("DOMContentLoaded", function () { + addPostTarget(); +}, false); + + +function addPostTarget() +{ + let frameName = location.search.substr(1); + let form = document.getElementById("postform"); + let iframe = document.createElement("iframe"); + iframe.style.border = "1px solid red"; + iframe.src = "about:blank"; + form.target = iframe.name = iframe.id = frameName; + document.body.appendChild(iframe); + + let didSubmit = false; + iframe.onload = function() { + if (!didSubmit) { + didSubmit = true; + let submitButton = document.getElementById("submitButton"); + submitButton.click(); + } else { + // Form submission complete. Report iframe's name to test driver. + opener.postMessage({ state: "formPostDone", winName: iframe.name }, "*"); + } + }; +} + +</script> +<form name="postform" id="postform" + action="data:text/plain;charset=utf-8,Hello%20world" + method="POST" enctype="multipart/form-data"> + <input type="hidden" name="field1" value="value1"><br> + <input id="submitButton" type="submit" value="Post It"> +</body> +</html> diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml index 76a7c4249163..8cf9a90626cc 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -9478,7 +9478,7 @@ - name: privacy.window.name.update.enabled type: bool - value: true + value: false mirror: always # By default, the network state isolation is not active when there is a proxy
1 0
0 0
[tor-browser/tor-browser-87.0b4-10.5-1] Bug 13252: Do not store data in the app bundle
by sysrqb@torproject.org 11 Mar '21

11 Mar '21
commit 561bf424a1d18c025a600b2fbacef0a67ca642c5 Author: Kathy Brade <brade(a)pearlcrescent.com> Date: Fri Mar 18 14:20:02 2016 -0400 Bug 13252: Do not store data in the app bundle When --enable-tor-browser-data-outside-app-dir is enabled, all user data is stored in a directory named TorBrowser-Data which is located next to the application directory. Display an informative error message if the TorBrowser-Data directory cannot be created due to an "access denied" or a "read only volume" error. On Mac OS, add support for the --invisible command line option which is used by the meek-http-helper to avoid showing an icon for the helper browser on the dock. --- toolkit/xre/nsAppRunner.cpp | 76 +++++++++++++++---- toolkit/xre/nsXREDirProvider.cpp | 43 +++++------ toolkit/xre/nsXREDirProvider.h | 6 ++ xpcom/io/TorFileUtils.cpp | 133 +++++++++++++++++++++++++++++++++ xpcom/io/TorFileUtils.h | 32 ++++++++ xpcom/io/moz.build | 5 ++ xpcom/io/nsAppFileLocationProvider.cpp | 53 ++++++------- 7 files changed, 280 insertions(+), 68 deletions(-) diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index 904c89f7fb4b..8aa956feff7e 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -2418,6 +2418,8 @@ static nsresult ProfileMissingDialog(nsINativeAppSupport* aNative) { } } +// If aUnlocker is NULL, it is also OK for the following arguments to be NULL: +// aProfileDir, aProfileLocalDir, aResult. static ReturnAbortOnError ProfileErrorDialog(nsIFile* aProfileDir, nsIFile* aProfileLocalDir, ProfileStatus aStatus, @@ -2426,17 +2428,19 @@ static ReturnAbortOnError ProfileErrorDialog(nsIFile* aProfileDir, nsIProfileLock** aResult) { nsresult rv; - bool exists; - aProfileDir->Exists(&exists); - if (!exists) { - return ProfileMissingDialog(aNative); + if (aProfileDir) { + bool exists; + aProfileDir->Exists(&exists); + if (!exists) { + return ProfileMissingDialog(aNative); + } } ScopedXPCOMStartup xpcom; rv = xpcom.Initialize(); NS_ENSURE_SUCCESS(rv, rv); - mozilla::Telemetry::WriteFailedProfileLock(aProfileDir); + if (aProfileDir) mozilla::Telemetry::WriteFailedProfileLock(aProfileDir); rv = xpcom.SetWindowCreator(aNative); NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); @@ -2526,7 +2530,8 @@ static ReturnAbortOnError ProfileErrorDialog(nsIFile* aProfileDir, } } else { #ifdef MOZ_WIDGET_ANDROID - if (java::GeckoAppShell::UnlockProfile()) { + if (aProfileDir && aProfileLocalDir && aResult && + java::GeckoAppShell::UnlockProfile()) { return NS_LockProfilePath(aProfileDir, aProfileLocalDir, nullptr, aResult); } @@ -2635,6 +2640,23 @@ static ReturnAbortOnError ShowProfileManager( return LaunchChild(false, true); } +#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR +static ProfileStatus CheckTorBrowserDataWriteAccess(nsIFile* aAppDir) { + // Check whether we can write to the directory that will contain + // TorBrowser-Data. + nsCOMPtr<nsIFile> tbDataDir; + RefPtr<nsXREDirProvider> dirProvider = nsXREDirProvider::GetSingleton(); + if (!dirProvider) return PROFILE_STATUS_OTHER_ERROR; + nsresult rv = + dirProvider->GetTorBrowserUserDataDir(getter_AddRefs(tbDataDir)); + NS_ENSURE_SUCCESS(rv, PROFILE_STATUS_OTHER_ERROR); + nsCOMPtr<nsIFile> tbDataDirParent; + rv = tbDataDir->GetParent(getter_AddRefs(tbDataDirParent)); + NS_ENSURE_SUCCESS(rv, PROFILE_STATUS_OTHER_ERROR); + return nsToolkitProfileService::CheckProfileWriteAccess(tbDataDirParent); +} +#endif + static bool gDoMigration = false; static bool gDoProfileReset = false; static nsCOMPtr<nsIToolkitProfile> gResetOldProfile; @@ -3677,6 +3699,14 @@ int XREMain::XRE_mainInit(bool* aExitFlag) { if (PR_GetEnv("XRE_MAIN_BREAK")) NS_BREAK(); #endif +#if defined(XP_MACOSX) && defined(TOR_BROWSER_DATA_OUTSIDE_APP_DIR) + bool hideDockIcon = (CheckArg("invisible") == ARG_FOUND); + if (hideDockIcon) { + ProcessSerialNumber psn = {0, kCurrentProcess}; + TransformProcessType(&psn, kProcessTransformToBackgroundApplication); + } +#endif + IncreaseDescriptorLimits(); #ifdef USE_GLX_TEST @@ -4538,7 +4568,34 @@ int XREMain::XRE_mainStartup(bool* aExitFlag) { return 0; } +#if (defined(MOZ_UPDATER) && !defined(MOZ_WIDGET_ANDROID)) || \ + defined(TOR_BROWSER_DATA_OUTSIDE_APP_DIR) + nsCOMPtr<nsIFile> exeFile, exeDir; + bool persistent; + rv = mDirProvider.GetFile(XRE_EXECUTABLE_FILE, &persistent, + getter_AddRefs(exeFile)); + NS_ENSURE_SUCCESS(rv, 1); + rv = exeFile->GetParent(getter_AddRefs(exeDir)); + NS_ENSURE_SUCCESS(rv, 1); +#endif + rv = NS_NewToolkitProfileService(getter_AddRefs(mProfileSvc)); +#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR + if (NS_FAILED(rv)) { + // NS_NewToolkitProfileService() returns a generic NS_ERROR_FAILURE error + // if creation of the TorBrowser-Data directory fails due to access denied + // or because of a read-only disk volume. Do an extra check here to detect + // these errors so we can display an informative error message. + ProfileStatus status = CheckTorBrowserDataWriteAccess(exeDir); + if ((PROFILE_STATUS_ACCESS_DENIED == status) || + (PROFILE_STATUS_READ_ONLY == status)) { + ProfileErrorDialog(nullptr, nullptr, status, nullptr, mNativeApp, + nullptr); + return 1; + } + } +#endif + if (rv == NS_ERROR_FILE_ACCESS_DENIED) { PR_fprintf(PR_STDERR, "Error: Access was denied while trying to open files in " @@ -4620,7 +4677,6 @@ int XREMain::XRE_mainStartup(bool* aExitFlag) { #if defined(MOZ_UPDATER) && !defined(MOZ_WIDGET_ANDROID) // Check for and process any available updates nsCOMPtr<nsIFile> updRoot; - bool persistent; rv = mDirProvider.GetFile(XRE_UPDATE_ROOT_DIR, &persistent, getter_AddRefs(updRoot)); // XRE_UPDATE_ROOT_DIR may fail. Fallback to appDir if failed @@ -4656,12 +4712,6 @@ int XREMain::XRE_mainStartup(bool* aExitFlag) { if (CheckArg("test-process-updates")) { SaveToEnv("MOZ_TEST_PROCESS_UPDATES=1"); } - nsCOMPtr<nsIFile> exeFile, exeDir; - rv = mDirProvider.GetFile(XRE_EXECUTABLE_FILE, &persistent, - getter_AddRefs(exeFile)); - NS_ENSURE_SUCCESS(rv, 1); - rv = exeFile->GetParent(getter_AddRefs(exeDir)); - NS_ENSURE_SUCCESS(rv, 1); ProcessUpdates(mDirProvider.GetGREDir(), exeDir, updRoot, gRestartArgc, gRestartArgv, mAppData->version); if (EnvHasValue("MOZ_TEST_PROCESS_UPDATES")) { diff --git a/toolkit/xre/nsXREDirProvider.cpp b/toolkit/xre/nsXREDirProvider.cpp index 4a675eb79fa0..9cfcfec1c6ab 100644 --- a/toolkit/xre/nsXREDirProvider.cpp +++ b/toolkit/xre/nsXREDirProvider.cpp @@ -51,6 +51,8 @@ #include "mozilla/XREAppData.h" #include "nsPrintfCString.h" +#include "TorFileUtils.h" + #include <stdlib.h> #ifdef XP_WIN @@ -1422,34 +1424,18 @@ nsresult nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile, return gDataDirHome->Clone(aFile); } - nsresult rv = GetAppDir()->Clone(getter_AddRefs(localDir)); + nsresult rv = GetTorBrowserUserDataDir(getter_AddRefs(localDir)); NS_ENSURE_SUCCESS(rv, rv); - int levelsToRemove = 1; // In FF21+, appDir points to browser subdirectory. -#if defined(XP_MACOSX) - levelsToRemove += 2; -#endif - while (localDir && (levelsToRemove > 0)) { - // When crawling up the hierarchy, components named "." do not count. - nsAutoCString removedName; - rv = localDir->GetNativeLeafName(removedName); - NS_ENSURE_SUCCESS(rv, rv); - bool didRemove = !removedName.Equals("."); - - // Remove a directory component. - nsCOMPtr<nsIFile> parentDir; - rv = localDir->GetParent(getter_AddRefs(parentDir)); - NS_ENSURE_SUCCESS(rv, rv); - localDir = parentDir; - if (didRemove) --levelsToRemove; - } - - if (!localDir) return NS_ERROR_FAILURE; - - rv = localDir->AppendRelativeNativePath("TorBrowser" XPCOM_FILE_PATH_SEPARATOR - "Data" XPCOM_FILE_PATH_SEPARATOR +#if !defined(ANDROID) +# ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR + rv = localDir->AppendNative("Browser"_ns); +# else + rv = localDir->AppendRelativeNativePath("Data" XPCOM_FILE_PATH_SEPARATOR "Browser"_ns); +# endif NS_ENSURE_SUCCESS(rv, rv); +#endif if (aLocal) { rv = localDir->AppendNative("Caches"_ns); @@ -1555,6 +1541,15 @@ nsresult nsXREDirProvider::GetUserDataDirectory(nsIFile** aFile, bool aLocal) { return NS_OK; } +nsresult nsXREDirProvider::GetTorBrowserUserDataDir(nsIFile** aFile) { + NS_ENSURE_ARG_POINTER(aFile); + nsCOMPtr<nsIFile> exeFile; + bool per = false; + nsresult rv = GetFile(XRE_EXECUTABLE_FILE, &per, getter_AddRefs(exeFile)); + NS_ENSURE_SUCCESS(rv, rv); + return TorBrowser_GetUserDataDir(exeFile, aFile); +} + nsresult nsXREDirProvider::EnsureDirectoryExists(nsIFile* aDirectory) { nsresult rv = aDirectory->Create(nsIFile::DIRECTORY_TYPE, 0700); diff --git a/toolkit/xre/nsXREDirProvider.h b/toolkit/xre/nsXREDirProvider.h index b9678d4ec577..2aa2face5974 100644 --- a/toolkit/xre/nsXREDirProvider.h +++ b/toolkit/xre/nsXREDirProvider.h @@ -113,6 +113,12 @@ class nsXREDirProvider final : public nsIDirectoryServiceProvider2, */ nsresult GetProfileDir(nsIFile** aResult); + /** + * Get the TorBrowser user data directory by calling the + * TorBrowser_GetUserDataDir() utility function. + */ + nsresult GetTorBrowserUserDataDir(nsIFile** aFile); + protected: nsresult GetFilesInternal(const char* aProperty, nsISimpleEnumerator** aResult); diff --git a/xpcom/io/TorFileUtils.cpp b/xpcom/io/TorFileUtils.cpp new file mode 100644 index 000000000000..6bd03f1f7fed --- /dev/null +++ b/xpcom/io/TorFileUtils.cpp @@ -0,0 +1,133 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "TorFileUtils.h" +#include "nsString.h" +#ifdef MOZ_WIDGET_COCOA +# include <Carbon/Carbon.h> +# include "nsILocalFileMac.h" +#endif + +static nsresult GetAppRootDir(nsIFile* aExeFile, nsIFile** aFile); + +//----------------------------------------------------------------------------- +nsresult TorBrowser_GetUserDataDir(nsIFile* aExeFile, nsIFile** aFile) { + NS_ENSURE_ARG_POINTER(aFile); + nsCOMPtr<nsIFile> tbDataDir; + +#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR + nsAutoCString tbDataLeafName("TorBrowser-Data"_ns); + nsCOMPtr<nsIFile> appRootDir; + nsresult rv = GetAppRootDir(aExeFile, getter_AddRefs(appRootDir)); + NS_ENSURE_SUCCESS(rv, rv); +# ifndef XP_MACOSX + // On all platforms except Mac OS, we always operate in a "portable" mode + // where the TorBrowser-Data directory is located next to the application. + rv = appRootDir->GetParent(getter_AddRefs(tbDataDir)); + NS_ENSURE_SUCCESS(rv, rv); + rv = tbDataDir->AppendNative(tbDataLeafName); + NS_ENSURE_SUCCESS(rv, rv); +# else + // For Mac OS, determine whether we should store user data in the OS's + // standard location (i.e., under ~/Library/Application Support). We use + // the OS location if (1) the application is installed in a directory whose + // path contains "/Applications" or (2) the TorBrowser-Data directory does + // not exist and cannot be created (which probably means we lack write + // permission to the directory that contains the application). + nsAutoString appRootPath; + rv = appRootDir->GetPath(appRootPath); + NS_ENSURE_SUCCESS(rv, rv); + bool useOSLocation = + (appRootPath.Find("/Applications", true /* ignore case */) >= 0); + if (!useOSLocation) { + // We hope to use the portable (aka side-by-side) approach, but before we + // commit to that, let's ensure that we can create the TorBrowser-Data + // directory. If it already exists, we will try to use it; if not and we + // fail to create it, we will switch to ~/Library/Application Support. + rv = appRootDir->GetParent(getter_AddRefs(tbDataDir)); + NS_ENSURE_SUCCESS(rv, rv); + rv = tbDataDir->AppendNative(tbDataLeafName); + NS_ENSURE_SUCCESS(rv, rv); + bool exists = false; + rv = tbDataDir->Exists(&exists); + if (NS_SUCCEEDED(rv) && !exists) + rv = tbDataDir->Create(nsIFile::DIRECTORY_TYPE, 0700); + useOSLocation = NS_FAILED(rv); + } + + if (useOSLocation) { + // We are using ~/Library/Application Support/TorBrowser-Data. We do not + // need to create that directory here because the code in nsXREDirProvider + // will do so (and the user should always have write permission for + // ~/Library/Application Support; if they do not we have no more options). + FSRef fsRef; + OSErr err = ::FSFindFolder(kUserDomain, kApplicationSupportFolderType, + kCreateFolder, &fsRef); + NS_ENSURE_FALSE(err, NS_ERROR_FAILURE); + // To convert the FSRef returned by FSFindFolder() into an nsIFile that + // points to ~/Library/Application Support, we first create an empty + // nsIFile object (no path) and then use InitWithFSRef() to set the + // path. + rv = NS_NewNativeLocalFile(""_ns, true, getter_AddRefs(tbDataDir)); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr<nsILocalFileMac> dirFileMac = do_QueryInterface(tbDataDir); + if (!dirFileMac) return NS_ERROR_UNEXPECTED; + rv = dirFileMac->InitWithFSRef(&fsRef); + NS_ENSURE_SUCCESS(rv, rv); + rv = tbDataDir->AppendNative(tbDataLeafName); + NS_ENSURE_SUCCESS(rv, rv); + } +# endif + +#elif defined(ANDROID) + // Tor Browser Android stores data in the app home directory. + const char* homeDir = getenv("HOME"); + if (!homeDir || !*homeDir) return NS_ERROR_FAILURE; + nsresult rv = NS_NewNativeLocalFile(nsDependentCString(homeDir), true, + getter_AddRefs(tbDataDir)); +#else + // User data is embedded within the application directory (i.e., + // TOR_BROWSER_DATA_OUTSIDE_APP_DIR is not defined). + nsresult rv = GetAppRootDir(aExeFile, getter_AddRefs(tbDataDir)); + NS_ENSURE_SUCCESS(rv, rv); + rv = tbDataDir->AppendNative("TorBrowser"_ns); + NS_ENSURE_SUCCESS(rv, rv); +#endif + + tbDataDir.forget(aFile); + return NS_OK; +} + +static nsresult GetAppRootDir(nsIFile* aExeFile, nsIFile** aFile) { + NS_ENSURE_ARG_POINTER(aExeFile); + NS_ENSURE_ARG_POINTER(aFile); + nsCOMPtr<nsIFile> appRootDir = aExeFile; + + int levelsToRemove = 1; // Remove firefox (the executable file). +#if defined(XP_MACOSX) + levelsToRemove += 2; // On Mac OS, we must also remove Contents/MacOS. +#endif + while (appRootDir && (levelsToRemove > 0)) { + // When crawling up the hierarchy, components named "." do not count. + nsAutoCString removedName; + nsresult rv = appRootDir->GetNativeLeafName(removedName); + NS_ENSURE_SUCCESS(rv, rv); + bool didRemove = !removedName.Equals("."); + + // Remove a directory component. + nsCOMPtr<nsIFile> parentDir; + rv = appRootDir->GetParent(getter_AddRefs(parentDir)); + NS_ENSURE_SUCCESS(rv, rv); + appRootDir = parentDir; + + if (didRemove) --levelsToRemove; + } + + if (!appRootDir) return NS_ERROR_FAILURE; + + appRootDir.forget(aFile); + return NS_OK; +} diff --git a/xpcom/io/TorFileUtils.h b/xpcom/io/TorFileUtils.h new file mode 100644 index 000000000000..31e70a7e0d3a --- /dev/null +++ b/xpcom/io/TorFileUtils.h @@ -0,0 +1,32 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef TorFileUtils_h__ +#define TorFileUtils_h__ + +#include "nsIFile.h" + +/** + * TorBrowser_GetUserDataDir + * + * Retrieve the Tor Browser user data directory. + * When built with --enable-tor-browser-data-outside-app-dir, the directory + * is next to the application directory, except on Mac OS where it may be + * there or it may be at ~/Library/Application Support/TorBrowser-Data (the + * latter location is used if the .app bundle is in a directory whose path + * contains /Applications or if we lack write access to the directory that + * contains the .app). + * When built without --enable-tor-browser-data-outside-app-dir, this + * directory is TorBrowser.app/TorBrowser. + * + * @param aExeFile The firefox executable. + * @param aFile Out parameter that is set to the Tor Browser user data + * directory. + * @return NS_OK on success. Error otherwise. + */ +extern nsresult TorBrowser_GetUserDataDir(nsIFile* aExeFile, nsIFile** aFile); + +#endif // !TorFileUtils_h__ diff --git a/xpcom/io/moz.build b/xpcom/io/moz.build index d28c426e7bd7..af7b5be04f6e 100644 --- a/xpcom/io/moz.build +++ b/xpcom/io/moz.build @@ -86,6 +86,7 @@ EXPORTS += [ "nsUnicharInputStream.h", "nsWildCard.h", "SpecialSystemDirectory.h", + "TorFileUtils.h", ] EXPORTS.mozilla += [ @@ -137,6 +138,10 @@ UNIFIED_SOURCES += [ "SpecialSystemDirectory.cpp", ] +SOURCES += [ + "TorFileUtils.cpp", +] + if CONFIG["MOZ_WIDGET_TOOLKIT"] == "cocoa": SOURCES += [ "CocoaFileUtils.mm", diff --git a/xpcom/io/nsAppFileLocationProvider.cpp b/xpcom/io/nsAppFileLocationProvider.cpp index 2bbcee92aedb..66f6940beff6 100644 --- a/xpcom/io/nsAppFileLocationProvider.cpp +++ b/xpcom/io/nsAppFileLocationProvider.cpp @@ -28,6 +28,8 @@ # include <sys/param.h> #endif +#include "TorFileUtils.h" + // WARNING: These hard coded names need to go away. They need to // come from localizable resources @@ -234,8 +236,14 @@ nsresult nsAppFileLocationProvider::CloneMozBinDirectory(nsIFile** aLocalFile) { // GetProductDirectory - Gets the directory which contains the application data // folder // +#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR +// UNIX and WIN : <App Folder>/../TorBrowser-Data/Browser +// Mac : <App Folder>/../../../TorBrowser-Data/Browser OR +// ~/Library/Application Support/TorBrowser-Data/Browser +#else // UNIX and WIN : <App Folder>/TorBrowser/Data/Browser // Mac : <App Folder>/../../TorBrowser/Data/Browser +#endif //---------------------------------------------------------------------------------------- nsresult nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile, bool aLocal) { @@ -243,42 +251,25 @@ nsresult nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile, return NS_ERROR_INVALID_ARG; } - nsresult rv; + nsresult rv = NS_ERROR_UNEXPECTED; bool exists; - nsCOMPtr<nsIFile> localDir; + nsCOMPtr<nsIFile> localDir, exeFile; - rv = CloneMozBinDirectory(getter_AddRefs(localDir)); + nsCOMPtr<nsIProperties> directoryService( + do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + rv = directoryService->Get(XRE_EXECUTABLE_FILE, NS_GET_IID(nsIFile), + getter_AddRefs(exeFile)); + NS_ENSURE_SUCCESS(rv, rv); + rv = TorBrowser_GetUserDataDir(exeFile, getter_AddRefs(localDir)); NS_ENSURE_SUCCESS(rv, rv); - int levelsToRemove = 1; // In FF21+, bin dir points to browser subdirectory. -#if defined(XP_MACOSX) - levelsToRemove += 2; -#endif - while (localDir && (levelsToRemove > 0)) { - // When crawling up the hierarchy, components named "." do not count. - nsAutoCString removedName; - rv = localDir->GetNativeLeafName(removedName); - NS_ENSURE_SUCCESS(rv, rv); - bool didRemove = !removedName.Equals("."); - - // Remove a directory component. - nsCOMPtr<nsIFile> parentDir; - rv = localDir->GetParent(getter_AddRefs(parentDir)); - NS_ENSURE_SUCCESS(rv, rv); - localDir = parentDir; - - if (didRemove) { - --levelsToRemove; - } - } - - if (!localDir) { - return NS_ERROR_FAILURE; - } - - rv = localDir->AppendRelativeNativePath("TorBrowser" XPCOM_FILE_PATH_SEPARATOR - "Data" XPCOM_FILE_PATH_SEPARATOR +#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR + rv = localDir->AppendNative("Browser"_ns); +#else + rv = localDir->AppendRelativeNativePath("Data" XPCOM_FILE_PATH_SEPARATOR "Browser"_ns); +#endif NS_ENSURE_SUCCESS(rv, rv); if (aLocal) {
1 0
0 0
[tor-browser/tor-browser-87.0b4-10.5-1] Bug 21724: Make Firefox and Tor Browser distinct macOS apps
by sysrqb@torproject.org 11 Mar '21

11 Mar '21
commit 373029038cf869f78cbce26467179eae80af6158 Author: teor <teor2345(a)gmail.com> Date: Mon Mar 13 23:06:23 2017 +1100 Bug 21724: Make Firefox and Tor Browser distinct macOS apps When macOS opens a document or selects a default browser, it sometimes uses the CFBundleSignature. Changing from the Firefox MOZB signature to a different signature TORB allows macOS to distinguish between Firefox and Tor Browser. --- browser/app/Makefile.in | 2 +- browser/app/macbuild/Contents/Info.plist.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/browser/app/Makefile.in b/browser/app/Makefile.in index 54d6b43fe126..8dd3a9a65661 100644 --- a/browser/app/Makefile.in +++ b/browser/app/Makefile.in @@ -102,5 +102,5 @@ ifdef MOZ_UPDATER mv -f '$(dist_dest)/Contents/MacOS/updater.app/Contents/MacOS/org.mozilla.updater' '$(dist_dest)/Contents/Library/LaunchServices' ln -s ../../../../Library/LaunchServices/org.mozilla.updater '$(dist_dest)/Contents/MacOS/updater.app/Contents/MacOS/org.mozilla.updater' endif - printf APPLMOZB > '$(dist_dest)/Contents/PkgInfo' + printf APPLTORB > '$(dist_dest)/Contents/PkgInfo' endif diff --git a/browser/app/macbuild/Contents/Info.plist.in b/browser/app/macbuild/Contents/Info.plist.in index fb5e6993ea9d..1d376c8d83d6 100644 --- a/browser/app/macbuild/Contents/Info.plist.in +++ b/browser/app/macbuild/Contents/Info.plist.in @@ -179,7 +179,7 @@ <key>CFBundleShortVersionString</key> <string>@APP_VERSION@</string> <key>CFBundleSignature</key> - <string>MOZB</string> + <string>TORB</string> <key>CFBundleURLTypes</key> <array> <dict>
1 0
0 0
[tor-browser/tor-browser-87.0b4-10.5-1] Bug 11641: change TBB directory structure to be more like Firefox's
by sysrqb@torproject.org 11 Mar '21

11 Mar '21
commit b063609e67cf00d426e320a55a03f901385f96ab Author: Kathy Brade <brade(a)pearlcrescent.com> Date: Tue Apr 29 13:08:24 2014 -0400 Bug 11641: change TBB directory structure to be more like Firefox's Unless the -osint command line flag is used, the browser now defaults to the equivalent of -no-remote. There is a new -allow-remote flag that may be used to restore the original (Firefox-like) default behavior. --- toolkit/xre/nsAppRunner.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index 8aa956feff7e..f33f6cfa4b44 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -1810,8 +1810,10 @@ static void DumpHelp() { " --migration Start with migration wizard.\n" " --ProfileManager Start with ProfileManager.\n" #ifdef MOZ_HAS_REMOTE - " --no-remote Do not accept or send remote commands; implies\n" + " --no-remote (default) Do not accept or send remote commands; " + "implies\n" " --new-instance.\n" + " --allow-remote Accept and send remote commands.\n" " --new-instance Open new instance, not a new window in running " "instance.\n" #endif @@ -4047,16 +4049,25 @@ int XREMain::XRE_mainInit(bool* aExitFlag) { gSafeMode); #if defined(MOZ_HAS_REMOTE) + // In Tor Browser, remoting is disabled by default unless -osint is used. + bool allowRemote = (CheckArg("allow-remote") == ARG_FOUND); + bool isOsint = (CheckArg("osint", nullptr, CheckArgFlag::None) == ARG_FOUND); + if (!allowRemote && !isOsint) { + SaveToEnv("MOZ_NO_REMOTE=1"); + } // Handle --no-remote and --new-instance command line arguments. Setup // the environment to better accommodate other components and various // restart scenarios. ar = CheckArg("no-remote"); - if (ar == ARG_FOUND || EnvHasValue("MOZ_NO_REMOTE")) { + if ((ar == ARG_FOUND) && allowRemote) { + PR_fprintf(PR_STDERR, + "Error: argument --no-remote is invalid when argument " + "--allow-remote is specified\n"); + return 1; + } + if (EnvHasValue("MOZ_NO_REMOTE")) { mDisableRemoteClient = true; mDisableRemoteServer = true; - if (!EnvHasValue("MOZ_NO_REMOTE")) { - SaveToEnv("MOZ_NO_REMOTE=1"); - } } ar = CheckArg("new-instance");
1 0
0 0
[tor-browser/tor-browser-87.0b4-10.5-1] Bug 18821: Disable libmdns for Android and Desktop
by sysrqb@torproject.org 11 Mar '21

11 Mar '21
commit cd9f9f610d7174ba010333811cbac765bf973d13 Author: Georg Koppen <gk(a)torproject.org> Date: Wed Apr 20 14:34:50 2016 +0000 Bug 18821: Disable libmdns for Android and Desktop There should be no need to remove the OS X support introduced in https://bugzilla.mozilla.org/show_bug.cgi?id=1225726 as enabling this is governed by a preference (which is actually set to `false`). However, we remove it at build time as well (defense in depth). This is basically a backout of the relevant passages of https://hg.mozilla.org/mozilla-central/rev/6bfb430de85d, https://hg.mozilla.org/mozilla-central/rev/609b337bf7ab and https://hg.mozilla.org/mozilla-central/rev/8e092ec5fbbd. Fixed bug 21861 (Disable additional mDNS code to avoid proxy bypasses) as well. --- dom/presentation/provider/components.conf | 10 ---------- dom/presentation/provider/moz.build | 1 - netwerk/dns/mdns/libmdns/components.conf | 15 --------------- netwerk/dns/mdns/libmdns/moz.build | 28 ---------------------------- 4 files changed, 54 deletions(-) diff --git a/dom/presentation/provider/components.conf b/dom/presentation/provider/components.conf index 04cb28ec757e..56994ed7cd94 100644 --- a/dom/presentation/provider/components.conf +++ b/dom/presentation/provider/components.conf @@ -6,9 +6,6 @@ categories = {} -if buildconfig.substs['MOZ_WIDGET_TOOLKIT'] in ('cocoa', 'android'): - categories["presentation-device-provider"] = "MulticastDNSDeviceProvider" - Classes = [ { 'cid': '{f4079b8b-ede5-4b90-a112-5b415a931deb}', @@ -16,11 +13,4 @@ Classes = [ 'jsm': 'resource://gre/modules/PresentationControlService.jsm', 'constructor': 'PresentationControlService', }, - { - 'cid': '{814f947a-52f7-41c9-94a1-3684797284ac}', - 'contract_ids': ['@mozilla.org/presentation-device/multicastdns-provider;1'], - 'type': 'mozilla::dom::presentation::MulticastDNSDeviceProvider', - 'headers': ['/dom/presentation/provider/MulticastDNSDeviceProvider.h'], - 'categories': categories, - }, ] diff --git a/dom/presentation/provider/moz.build b/dom/presentation/provider/moz.build index f6c4527d2cdf..9fab92997787 100644 --- a/dom/presentation/provider/moz.build +++ b/dom/presentation/provider/moz.build @@ -8,7 +8,6 @@ EXTRA_JS_MODULES += ["PresentationControlService.jsm"] UNIFIED_SOURCES += [ "DeviceProviderHelpers.cpp", - "MulticastDNSDeviceProvider.cpp", ] XPCOM_MANIFESTS += [ diff --git a/netwerk/dns/mdns/libmdns/components.conf b/netwerk/dns/mdns/libmdns/components.conf index 6e64140c820e..1b50dbf673a4 100644 --- a/netwerk/dns/mdns/libmdns/components.conf +++ b/netwerk/dns/mdns/libmdns/components.conf @@ -5,20 +5,5 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. Classes = [ - { - 'cid': '{14a50f2b-7ff6-48a5-88e3-615fd111f5d3}', - 'contract_ids': ['@mozilla.org/toolkit/components/mdnsresponder/dns-info;1'], - 'type': 'mozilla::net::nsDNSServiceInfo', - 'headers': ['/netwerk/dns/mdns/libmdns/nsDNSServiceInfo.h'], - }, ] -if buildconfig.substs['MOZ_WIDGET_TOOLKIT'] != 'cocoa': - Classes += [ - { - 'cid': '{f9346d98-f27a-4e89-b744-493843416480}', - 'contract_ids': ['@mozilla.org/toolkit/components/mdnsresponder/dns-sd;1'], - 'jsm': 'resource://gre/modules/DNSServiceDiscovery.jsm', - 'constructor': 'nsDNSServiceDiscovery', - }, - ] diff --git a/netwerk/dns/mdns/libmdns/moz.build b/netwerk/dns/mdns/libmdns/moz.build index f9c025fa823e..e6e70a6d803c 100644 --- a/netwerk/dns/mdns/libmdns/moz.build +++ b/netwerk/dns/mdns/libmdns/moz.build @@ -4,34 +4,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -if CONFIG["MOZ_WIDGET_TOOLKIT"] == "cocoa": - UNIFIED_SOURCES += [ - "MDNSResponderOperator.cpp", - "MDNSResponderReply.cpp", - "nsDNSServiceDiscovery.cpp", - ] - - LOCAL_INCLUDES += [ - "/netwerk/base", - ] - -else: - EXTRA_JS_MODULES += [ - "DNSServiceDiscovery.jsm", - "fallback/DataReader.jsm", - "fallback/DataWriter.jsm", - "fallback/DNSPacket.jsm", - "fallback/DNSRecord.jsm", - "fallback/DNSResourceRecord.jsm", - "fallback/DNSTypes.jsm", - "fallback/MulticastDNS.jsm", - ] - - if CONFIG["MOZ_WIDGET_TOOLKIT"] == "android": - EXTRA_JS_MODULES += [ - "MulticastDNSAndroid.jsm", - ] - UNIFIED_SOURCES += [ "nsDNSServiceInfo.cpp", ]
1 0
0 0
[tor-browser/tor-browser-87.0b4-10.5-1] Bug 18800: Remove localhost DNS lookup in nsProfileLock.cpp
by sysrqb@torproject.org 11 Mar '21

11 Mar '21
commit f3144564bd9213ddd41115781edb3e1c050f8754 Author: Kathy Brade <brade(a)pearlcrescent.com> Date: Thu Apr 21 10:40:26 2016 -0400 Bug 18800: Remove localhost DNS lookup in nsProfileLock.cpp Instead of using the local computer's IP address within symlink-based profile lock signatures, always use 127.0.0.1. --- toolkit/profile/nsProfileLock.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/toolkit/profile/nsProfileLock.cpp b/toolkit/profile/nsProfileLock.cpp index 01818d32e6f7..adccfa4dd6d4 100644 --- a/toolkit/profile/nsProfileLock.cpp +++ b/toolkit/profile/nsProfileLock.cpp @@ -289,18 +289,17 @@ nsresult nsProfileLock::LockWithSymlink(nsIFile* aLockFile, if (!mReplacedLockTime) aLockFile->GetLastModifiedTimeOfLink(&mReplacedLockTime); + // For Tor Browser, avoid a DNS lookup here so the Tor network is not + // bypassed. Instead, always use 127.0.0.1 for the IP address portion + // of the lock signature, which may cause the browser to refuse to + // start in the rare event that all of the following conditions are met: + // 1. The browser profile is on a network file system. + // 2. The file system does not support fcntl() locking. + // 3. Tor Browser is run from two different computers at the same time. + struct in_addr inaddr; inaddr.s_addr = htonl(INADDR_LOOPBACK); - char hostname[256]; - PRStatus status = PR_GetSystemInfo(PR_SI_HOSTNAME, hostname, sizeof hostname); - if (status == PR_SUCCESS) { - char netdbbuf[PR_NETDB_BUF_SIZE]; - PRHostEnt hostent; - status = PR_GetHostByName(hostname, netdbbuf, sizeof netdbbuf, &hostent); - if (status == PR_SUCCESS) memcpy(&inaddr, hostent.h_addr, sizeof inaddr); - } - mozilla::SmprintfPointer signature = mozilla::Smprintf("%s:%s%lu", inet_ntoa(inaddr), aHaveFcntlLock ? "+" : "", (unsigned long)getpid());
1 0
0 0
[tor-browser/tor-browser-87.0b4-10.5-1] Bug 19273: Avoid JavaScript patching of the external app helper dialog.
by sysrqb@torproject.org 11 Mar '21

11 Mar '21
commit 49cea828cc49c1f6daa9604848bd1a9a1f425a86 Author: Kathy Brade <brade(a)pearlcrescent.com> Date: Tue Jun 28 15:13:05 2016 -0400 Bug 19273: Avoid JavaScript patching of the external app helper dialog. When handling an external URI or downloading a file, invoke Torbutton's external app blocker component (which will present a download warning dialog unless the user has checked the "Automatically download files from now on" box). For e10s compatibility, avoid using a modal dialog and instead use a callback interface (nsIHelperAppWarningLauncher) to allow Torbutton to indicate the user's desire to cancel or continue each request. Other bugs fixed: Bug 21766: Crash with e10s enabled while trying to download a file Bug 21886: Download is stalled in non-e10s mode Bug 22471: Downloading files via the PDF viewer download button is broken Bug 22472: Fix FTP downloads when external helper app dialog is shown Bug 22610: Avoid crashes when canceling external helper app downloads Bug 22618: Downloading pdf file via file:/// is stalling --- .../exthandler/nsExternalHelperAppService.cpp | 172 ++++++++++++++++++--- uriloader/exthandler/nsExternalHelperAppService.h | 3 + .../exthandler/nsIExternalHelperAppService.idl | 47 ++++++ 3 files changed, 204 insertions(+), 18 deletions(-) diff --git a/uriloader/exthandler/nsExternalHelperAppService.cpp b/uriloader/exthandler/nsExternalHelperAppService.cpp index 92927822d792..c02a03d27d2c 100644 --- a/uriloader/exthandler/nsExternalHelperAppService.cpp +++ b/uriloader/exthandler/nsExternalHelperAppService.cpp @@ -133,6 +133,9 @@ static const char NEVER_ASK_FOR_SAVE_TO_DISK_PREF[] = static const char NEVER_ASK_FOR_OPEN_FILE_PREF[] = "browser.helperApps.neverAsk.openFile"; +static const char WARNING_DIALOG_CONTRACT_ID[] = + "@torproject.org/torbutton-extAppBlocker;1"; + // Helper functions for Content-Disposition headers /** @@ -405,6 +408,22 @@ static nsresult GetDownloadDirectory(nsIFile** _directory, return NS_OK; } +static already_AddRefed<nsIInterfaceRequestor> GetDialogParentAux( + BrowsingContext* aBrowsingContext, nsIInterfaceRequestor* aWindowContext) { + nsCOMPtr<nsIInterfaceRequestor> dialogParent = aWindowContext; + + if (!dialogParent && aBrowsingContext) { + dialogParent = do_QueryInterface(aBrowsingContext->GetDOMWindow()); + } + if (!dialogParent && aBrowsingContext && XRE_IsParentProcess()) { + RefPtr<Element> element = aBrowsingContext->Top()->GetEmbedderElement(); + if (element) { + dialogParent = do_QueryInterface(element->OwnerDoc()->GetWindow()); + } + } + return dialogParent.forget(); +} + /** * Structure for storing extension->type mappings. * @see defaultMimeEntries @@ -608,6 +627,92 @@ static const char* descriptionOverwriteExtensions[] = { "avif", "pdf", "svg", "webp", "xml", }; +////////////////////////////////////////////////////////////////////////////////////////////////////// +// begin nsExternalLoadURIHandler class definition and implementation +////////////////////////////////////////////////////////////////////////////////////////////////////// +class nsExternalLoadURIHandler final : public nsIHelperAppWarningLauncher { + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIHELPERAPPWARNINGLAUNCHER + + nsExternalLoadURIHandler(nsIHandlerInfo* aHandlerInfo, nsIURI* aURI, + nsIPrincipal* aTriggeringPrincipal, + BrowsingContext* aBrowsingContext); + + protected: + ~nsExternalLoadURIHandler(); + + nsCOMPtr<nsIHandlerInfo> mHandlerInfo; + nsCOMPtr<nsIURI> mURI; + nsCOMPtr<nsIPrincipal> mTriggeringPrincipal; + RefPtr<BrowsingContext> mBrowsingContext; + nsCOMPtr<nsIHelperAppWarningDialog> mWarningDialog; +}; + +NS_IMPL_ADDREF(nsExternalLoadURIHandler) +NS_IMPL_RELEASE(nsExternalLoadURIHandler) + +NS_INTERFACE_MAP_BEGIN(nsExternalLoadURIHandler) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIHelperAppWarningLauncher) + NS_INTERFACE_MAP_ENTRY(nsIHelperAppWarningLauncher) +NS_INTERFACE_MAP_END + +nsExternalLoadURIHandler::nsExternalLoadURIHandler( + nsIHandlerInfo* aHandlerInfo, nsIURI* aURI, + nsIPrincipal* aTriggeringPrincipal, BrowsingContext* aBrowsingContext) + : mHandlerInfo(aHandlerInfo), + mURI(aURI), + mTriggeringPrincipal(aTriggeringPrincipal), + mBrowsingContext(aBrowsingContext) + +{ + nsresult rv = NS_OK; + mWarningDialog = do_CreateInstance(WARNING_DIALOG_CONTRACT_ID, &rv); + if (NS_SUCCEEDED(rv) && mWarningDialog) { + // This will create a reference cycle (the dialog holds a reference to us + // as nsIHelperAppWarningLauncher), which will be broken in ContinueRequest + // or CancelRequest. + nsCOMPtr<nsIInterfaceRequestor> dialogParent = + GetDialogParentAux(aBrowsingContext, nullptr); + rv = mWarningDialog->MaybeShow(this, dialogParent); + } + + if (NS_FAILED(rv)) { + // If for some reason we could not open the download warning prompt, + // continue with the request. + ContinueRequest(); + } +} + +nsExternalLoadURIHandler::~nsExternalLoadURIHandler() {} + +NS_IMETHODIMP nsExternalLoadURIHandler::ContinueRequest() { + MOZ_ASSERT(mURI); + MOZ_ASSERT(mHandlerInfo); + + // Break our reference cycle with the download warning dialog (set up in + // LoadURI). + mWarningDialog = nullptr; + + nsresult rv = NS_OK; + nsCOMPtr<nsIContentDispatchChooser> chooser = + do_CreateInstance("@mozilla.org/content-dispatch-chooser;1", &rv); + NS_ENSURE_SUCCESS(rv, rv); + + return chooser->HandleURI(mHandlerInfo, mURI, mTriggeringPrincipal, + mBrowsingContext); +} + +NS_IMETHODIMP nsExternalLoadURIHandler::CancelRequest(nsresult aReason) { + NS_ENSURE_ARG(NS_FAILED(aReason)); + + // Break our reference cycle with the download warning dialog (set up in + // LoadURI). + mWarningDialog = nullptr; + + return NS_OK; +} + static StaticRefPtr<nsExternalHelperAppService> sExtHelperAppSvcSingleton; /** @@ -634,6 +739,9 @@ nsExternalHelperAppService::GetSingleton() { return do_AddRef(sExtHelperAppSvcSingleton); } +////////////////////////////////////////////////////////////////////////////////////////////////////// +// nsExternalHelperAppService definition and implementation +////////////////////////////////////////////////////////////////////////////////////////////////////// NS_IMPL_ISUPPORTS(nsExternalHelperAppService, nsIExternalHelperAppService, nsPIExternalAppLauncher, nsIExternalProtocolService, nsIMIMEService, nsIObserver, nsISupportsWeakReference) @@ -1091,12 +1199,13 @@ nsExternalHelperAppService::LoadURI(nsIURI* aURI, rv = GetProtocolHandlerInfo(scheme, getter_AddRefs(handler)); NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr<nsIContentDispatchChooser> chooser = - do_CreateInstance("@mozilla.org/content-dispatch-chooser;1", &rv); - NS_ENSURE_SUCCESS(rv, rv); + RefPtr<nsExternalLoadURIHandler> h = new nsExternalLoadURIHandler( + handler, uri, aTriggeringPrincipal, aBrowsingContext); + if (!h) { + return NS_ERROR_OUT_OF_MEMORY; + } - return chooser->HandleURI(handler, uri, aTriggeringPrincipal, - aBrowsingContext); + return NS_OK; } ////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1241,6 +1350,7 @@ NS_INTERFACE_MAP_BEGIN(nsExternalAppHandler) NS_INTERFACE_MAP_ENTRY(nsIStreamListener) NS_INTERFACE_MAP_ENTRY(nsIRequestObserver) NS_INTERFACE_MAP_ENTRY(nsIHelperAppLauncher) + NS_INTERFACE_MAP_ENTRY(nsIHelperAppWarningLauncher) NS_INTERFACE_MAP_ENTRY(nsICancelable) NS_INTERFACE_MAP_ENTRY(nsIBackgroundFileSaverObserver) NS_INTERFACE_MAP_ENTRY(nsINamed) @@ -1639,18 +1749,7 @@ void nsExternalAppHandler::MaybeApplyDecodingForExtension( already_AddRefed<nsIInterfaceRequestor> nsExternalAppHandler::GetDialogParent() { - nsCOMPtr<nsIInterfaceRequestor> dialogParent = mWindowContext; - - if (!dialogParent && mBrowsingContext) { - dialogParent = do_QueryInterface(mBrowsingContext->GetDOMWindow()); - } - if (!dialogParent && mBrowsingContext && XRE_IsParentProcess()) { - RefPtr<Element> element = mBrowsingContext->Top()->GetEmbedderElement(); - if (element) { - dialogParent = do_QueryInterface(element->OwnerDoc()->GetWindow()); - } - } - return dialogParent.forget(); + return GetDialogParentAux(mBrowsingContext, mWindowContext); } NS_IMETHODIMP nsExternalAppHandler::OnStartRequest(nsIRequest* request) { @@ -1778,6 +1877,34 @@ NS_IMETHODIMP nsExternalAppHandler::OnStartRequest(nsIRequest* request) { loadInfo->SetForceAllowDataURI(true); } + mWarningDialog = do_CreateInstance(WARNING_DIALOG_CONTRACT_ID, &rv); + if (NS_SUCCEEDED(rv) && mWarningDialog) { + // This will create a reference cycle (the dialog holds a reference to us + // as nsIHelperAppWarningLauncher), which will be broken in ContinueRequest + // or CancelRequest. + nsCOMPtr<nsIInterfaceRequestor> dialogParent = GetDialogParent(); + rv = mWarningDialog->MaybeShow(this, dialogParent); + } + + if (NS_FAILED(rv)) { + // If for some reason we could not open the download warning prompt, + // continue with the request. + ContinueRequest(); + } + + return NS_OK; +} + +NS_IMETHODIMP nsExternalAppHandler::ContinueRequest() { + nsAutoCString MIMEType; + if (mMimeInfo) { + mMimeInfo->GetMIMEType(MIMEType); + } + + // Break our reference cycle with the download warning dialog (set up in + // OnStartRequest). + mWarningDialog = nullptr; + // now that the temp file is set up, find out if we need to invoke a dialog // asking the user what they want us to do with this content... @@ -1861,6 +1988,7 @@ NS_IMETHODIMP nsExternalAppHandler::OnStartRequest(nsIRequest* request) { action = nsIMIMEInfo::saveToDisk; } + nsresult rv = NS_OK; if (alwaysAsk) { // Display the dialog mDialog = do_CreateInstance(NS_HELPERAPPLAUNCHERDLG_CONTRACTID, &rv); @@ -1917,6 +2045,14 @@ NS_IMETHODIMP nsExternalAppHandler::OnStartRequest(nsIRequest* request) { return NS_OK; } +NS_IMETHODIMP nsExternalAppHandler::CancelRequest(nsresult aReason) { + // Break our reference cycle with the download warning dialog (set up in + // OnStartRequest). + mWarningDialog = nullptr; + + return Cancel(aReason); +} + // Convert error info into proper message text and send OnStatusChange // notification to the dialog progress listener or nsITransfer implementation. void nsExternalAppHandler::SendStatusChange(ErrorType type, nsresult rv, @@ -2588,7 +2724,7 @@ NS_IMETHODIMP nsExternalAppHandler::Cancel(nsresult aReason) { } // Break our reference cycle with the helper app dialog (set up in - // OnStartRequest) + // ContinueRequest) mDialog = nullptr; mRequest = nullptr; diff --git a/uriloader/exthandler/nsExternalHelperAppService.h b/uriloader/exthandler/nsExternalHelperAppService.h index 8c87587e9ee7..9f149a560ab7 100644 --- a/uriloader/exthandler/nsExternalHelperAppService.h +++ b/uriloader/exthandler/nsExternalHelperAppService.h @@ -218,6 +218,7 @@ class nsExternalHelperAppService : public nsIExternalHelperAppService, */ class nsExternalAppHandler final : public nsIStreamListener, public nsIHelperAppLauncher, + public nsIHelperAppWarningLauncher, public nsIBackgroundFileSaverObserver, public nsINamed { public: @@ -225,6 +226,7 @@ class nsExternalAppHandler final : public nsIStreamListener, NS_DECL_NSISTREAMLISTENER NS_DECL_NSIREQUESTOBSERVER NS_DECL_NSIHELPERAPPLAUNCHER + NS_DECL_NSIHELPERAPPWARNINGLAUNCHER NS_DECL_NSICANCELABLE NS_DECL_NSIBACKGROUNDFILESAVEROBSERVER NS_DECL_NSINAMED @@ -496,6 +498,7 @@ class nsExternalAppHandler final : public nsIStreamListener, nsCOMPtr<nsITransfer> mTransfer; nsCOMPtr<nsIHelperAppLauncherDialog> mDialog; + nsCOMPtr<nsIHelperAppWarningDialog> mWarningDialog; /** diff --git a/uriloader/exthandler/nsIExternalHelperAppService.idl b/uriloader/exthandler/nsIExternalHelperAppService.idl index 657e15bc0742..ebdb1cdacf78 100644 --- a/uriloader/exthandler/nsIExternalHelperAppService.idl +++ b/uriloader/exthandler/nsIExternalHelperAppService.idl @@ -177,3 +177,50 @@ interface nsIHelperAppLauncher : nsICancelable */ readonly attribute uint64_t browsingContextId; }; + +/** + * nsIHelperAppWarningLauncher is implemented by two classes: + * nsExternalLoadURIHandler + * nsExternalAppHandler + */ +[scriptable, uuid(cffd508b-4aaf-43ad-99c6-671d35cbc558)] +interface nsIHelperAppWarningLauncher : nsISupports +{ + /** + * Callback invoked by the external app warning dialog to continue the + * request. + * NOTE: This will release the reference to the nsIHelperAppWarningDialog. + */ + void continueRequest(); + + /** + * Callback invoked by the external app warning dialog to cancel the request. + * NOTE: This will release the reference to the nsIHelperAppWarningDialog. + * + * @param aReason + * Pass a failure code to indicate the reason why this operation is + * being canceled. It is an error to pass a success code. + */ + void cancelRequest(in nsresult aReason); +}; + +/** + * nsIHelperAppWarningDialog is implemented by Torbutton's external app + * blocker (src/components/external-app-blocker.js). + */ +[scriptable, uuid(f4899a3f-0df3-42cc-9db8-bdf599e5a208)] +interface nsIHelperAppWarningDialog : nsISupports +{ + /** + * Possibly show a launch warning dialog (it will not be shown if the user + * has chosen to not see the warning again). + * + * @param aLauncher + * A nsIHelperAppWarningLauncher to be invoked after the user confirms + * or cancels the download. + * @param aWindowContext + * The window associated with the download. + */ + void maybeShow(in nsIHelperAppWarningLauncher aLauncher, + in nsISupports aWindowContext); +};
1 0
0 0
  • ← Newer
  • 1
  • ...
  • 443
  • 444
  • 445
  • 446
  • 447
  • 448
  • 449
  • ...
  • 818
  • Older →

HyperKitty Powered by HyperKitty version 1.3.12.