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 -----
  • 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
  • 20057 discussions
[tor-browser/tor-browser-78.5.0esr-10.0-1] Bug 12620: TorBrowser regression tests
by gk@torproject.org 12 Nov '20

12 Nov '20
commit f8b3423da80cb2ca2c82f0ae785580870ee8719e 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 | 60 +++++++++++++++ tbb-tests/browser.ini | 5 ++ tbb-tests/browser_tor_TB4.js | 162 +++++++++++++++++++++++++++++++++++++++ tbb-tests/browser_tor_bug2950.js | 74 ++++++++++++++++++ tbb-tests/mochitest.ini | 3 + tbb-tests/moz.build | 10 +++ tbb-tests/test_tor_bug2874.html | 25 ++++++ toolkit/toolkit.mozbuild | 3 +- 8 files changed, 341 insertions(+), 1 deletion(-) diff --git a/run-tbb-tests b/run-tbb-tests new file mode 100755 index 000000000000..5e266f9ba4cd --- /dev/null +++ b/run-tbb-tests @@ -0,0 +1,60 @@ +#!/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='%an %H' | grep '^ffxbld ' \ + | head -1 | cut -d ' ' -f 2) + + 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' +./mach mochitest --log-tbpl tbb-tests.log --setpref security.nocertdb=false \ + "${tests[@]}" + +echo "*************************" +echo "*************************" +echo "Summary of failed tests:" +grep --color=never TEST-UNEXPECTED-FAIL tbb-tests.log 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..af688bee0226 --- /dev/null +++ b/tbb-tests/browser_tor_TB4.js @@ -0,0 +1,162 @@ +// # Test for TB4: Tor Browser's Firefox preference overrides +// Simple regression tests to check the value of each pref and +// decides if it is set as expected. + +// TODO: Write unit tests to check that each pref setting here +// causes the browser to have the desired behavior (a big task). + +function test() { + +let expectedPrefs = [ + // Disable browser auto updaters and associated homepage notifications + ["app.update.auto", false], + ["app.update.enabled", false], + ["browser.search.update", false], + ["browser.rights.3.shown", true], + ["browser.startup.homepage_override.mstone", "ignore"], + ["startup.homepage_welcome_url", ""], + ["startup.homepage_override_url", ""], + + // Disable the "Refresh" prompt that is displayed for stale profiles. + ["browser.disableResetPrompt", true], + + // Disk activity: Disable Browsing History Storage + ["browser.privatebrowsing.autostart", true], + ["browser.cache.disk.enable", false], + ["browser.cache.offline.enable", false], + ["dom.indexedDB.enabled", false], + ["permissions.memory_only", true], + ["network.cookie.lifetimePolicy", 2], + ["security.nocertdb", true], + + // Disk activity: TBB Directory Isolation + ["browser.download.useDownloadDir", false], + ["browser.shell.checkDefaultBrowser", false], + ["browser.download.manager.addToRecentDocs", false], + + // Misc privacy: Disk + ["signon.rememberSignons", false], + ["browser.formfill.enable", false], + ["signon.autofillForms", false], + ["browser.sessionstore.privacy_level", 2], + ["media.cache_size", 0], + + // Misc privacy: Remote + ["browser.send_pings", false], + ["geo.enabled", false], + ["geo.wifi.uri", ""], + ["browser.search.suggest.enabled", false], + ["browser.safebrowsing.malware.enabled", false], + ["extensions.ui.lastCategory", "addons://list/extension"], + ["datareporting.healthreport.uploadEnabled", false], + ["datareporting.policy.dataSubmissionEnabled", false], + ["security.mixed_content.block_active_content", false], // Disable until https://bugzilla.mozilla.org/show_bug.cgi?id=878890 is patched + ["browser.syncPromoViewsLeftMap", "{\"addons\":0, \"passwords\":0, \"bookmarks\":0}"], // Don't promote sync + ["services.sync.engine.prefs", false], // Never sync prefs, addons, or tabs with other browsers + ["services.sync.engine.addons", false], + ["services.sync.engine.tabs", false], + ["extensions.getAddons.cache.enabled", false], // https://blog.mozilla.org/addons/how-to-opt-out-of-add-on-metadata-updates/ + + // Fingerprinting + ["webgl.min_capability_mode", true], + ["webgl.disable-extensions", true], + ["dom.battery.enabled", false], // fingerprinting due to differing OS implementations + ["browser.display.max_font_attempts",10], + ["browser.display.max_font_count",10], + ["gfx.downloadable_fonts.fallback_delay", -1], + ["browser.startup.homepage_override.buildID", "20100101"], + + // Third party stuff + ["network.cookie.cookieBehavior", 1], + ["security.enable_tls_session_tickets", false], + ["network.http.spdy.enabled", false], // Stores state and may have keepalive issues (both fixable) + ["network.http.spdy.enabled.v2", false], // Seems redundant, but just in case + ["network.http.spdy.enabled.v3", false], // Seems redundant, but just in case + + // Proxy and proxy security + ["network.proxy.socks", "127.0.0.1"], + ["network.proxy.socks_port", 9150], + ["network.proxy.socks_remote_dns", true], + ["network.proxy.no_proxies_on", ""], // For fingerprinting and local service vulns (#10419) + ["network.proxy.type", 1], + ["network.security.ports.banned", "9050,9051,9150,9151"], + ["network.dns.disablePrefetch", true], + ["network.protocol-handler.external-default", false], + ["network.protocol-handler.external.mailto", false], + ["network.protocol-handler.external.news", false], + ["network.protocol-handler.external.nntp", false], + ["network.protocol-handler.external.snews", false], + ["network.protocol-handler.warn-external.mailto", true], + ["network.protocol-handler.warn-external.news", true], + ["network.protocol-handler.warn-external.nntp", true], + ["network.protocol-handler.warn-external.snews", true], + + // Network and performance + ["network.http.pipelining", true], + ["network.http.pipelining.aggressive", true], + ["network.http.pipelining.maxrequests", 12], + ["network.http.pipelining.ssl", true], + ["network.http.proxy.pipelining", true], + ["security.ssl.enable_false_start", true], + ["network.http.keep-alive.timeout", 20], + ["network.http.connection-retry-timeout", 0], + ["network.http.max-persistent-connections-per-proxy", 256], + ["network.http.pipelining.reschedule-timeout", 15000], + ["network.http.pipelining.read-timeout", 60000], + // Hacked pref: Now means "Attempt to pipeline at least this many requests together" + ["network.http.pipelining.max-optimistic-requests", 3], + ["security.disable_session_identifiers", true], + + // Extension support + ["extensions.autoDisableScopes", 0], + ["extensions.bootstrappedAddons", "{}"], + ["extensions.checkCompatibility.4.*", false], + ["extensions.databaseSchema", 3], + ["extensions.enabledAddons", "https-everywhere%40eff.org:3.1.4,%7B73a6fe31-595d-460b-a920-fcc0f8843232%7D:2.6.6.1,torbutton%40torproject.org:1.5.2,ubufox%40ubuntu.com:2.6,%7B972ce4c6-7e08-4474-a285-3208198ce6fd%7D:17.0.5"], + ["extensions.enabledItems", "langpack-en-US@firefox.mozilla.org:,{73a6fe31-595d-460b-a920-fcc0f8843232}:1.9.9.57,{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.4,{972ce4c6-7e08-4474-a285-3208198ce6fd}:3.5.8"], + ["extensions.enabledScopes", 1], + ["extensions.pendingOperations", false], + ["xpinstall.whitelist.add", ""], + ["xpinstall.whitelist.add.36", ""], + + // Omnibox settings + ["keyword.URL", "https://startpage.com/do/search?q="], + + // Hacks/workarounds: Direct2D seems to crash w/ lots of video cards w/ MinGW? + // Nvida cards also experience crashes without the second pref set to disabled + ["gfx.direct2d.disabled", true], + ["layers.acceleration.disabled", true], + + // Security enhancements + // https://trac.torproject.org/projects/tor/ticket/9387#comment:17 + ["javascript.options.ion.content", false], + ["javascript.options.baselinejit.content", false], + ["javascript.options.asmjs", false], + ["javascript.options.typeinference", false], + + // Enable TLS 1.1 and 1.2: + // https://trac.torproject.org/projects/tor/ticket/11253 + ["security.tls.version.max", 3], + + // Version placeholder + ["torbrowser.version", "UNKNOWN"], + + ]; + +let getPref = function (prefName) { + let type = gPrefService.getPrefType(prefName); + if (type === gPrefService.PREF_INT) return gPrefService.getIntPref(prefName); + if (type === gPrefService.PREF_BOOL) return gPrefService.getBoolPref(prefName); + if (type === gPrefService.PREF_STRING) return gPrefService.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..010cc6356202 --- /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 + +// __uri(spec)__. +// Creates an nsIURI instance from a spec +// (string address such as "http://torproject.org"). +let uri = spec => Services.io.newURI(spec, null, null); + +// __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.set(uri(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.get(uri(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 = "http://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, (originalValue === 0) ? 1 : 0); + // Now read back the permission value again. + let newReadValue = getPermission(SITE, KEY); + // Compare to confirm that the permission + // value was successfully changed. + isnot(newReadValue, originalValue, "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..de8a41a67a5c --- /dev/null +++ b/tbb-tests/moz.build @@ -0,0 +1,10 @@ +# -*- 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 d092b8b22346..6e35a4602300 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-78.5.0esr-10.0-1] Bug 12974: Disable NTLM and Negotiate HTTP Auth
by gk@torproject.org 12 Nov '20

12 Nov '20
commit 29dd7947492900ef03983f9d5b2649357eefc8bf 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 99720475b9dd..1c08fcf3da7e 100644 --- a/extensions/auth/nsHttpNegotiateAuth.cpp +++ b/extensions/auth/nsHttpNegotiateAuth.cpp @@ -152,6 +152,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-78.5.0esr-10.0-1] Bug 13028: Prevent potential proxy bypass cases.
by gk@torproject.org 12 Nov '20

12 Nov '20
commit 82752a36c6a4f8cd8bc83bdaaf74e324806835ce 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-78.5.0esr-10.0-1] Bug 9173: Change the default Firefox profile directory to be TBB-relative.
by gk@torproject.org 12 Nov '20

12 Nov '20
commit a72dff2df4f80b6b6a43d3622dfe471d124cc081 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 | 150 ++++++---------------------- toolkit/xre/nsXREDirProvider.h | 16 +-- xpcom/io/nsAppFileLocationProvider.cpp | 97 +++++++----------- 6 files changed, 84 insertions(+), 188 deletions(-) diff --git a/toolkit/profile/nsToolkitProfileService.cpp b/toolkit/profile/nsToolkitProfileService.cpp index dc4811313b5e..a3e50f8c00d3 100644 --- a/toolkit/profile/nsToolkitProfileService.cpp +++ b/toolkit/profile/nsToolkitProfileService.cpp @@ -723,10 +723,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 ef72d1bf4fb2..4afec36f57bc 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -3187,7 +3187,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 0a2c0c342893..46735a293a00 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(NS_LITERAL_CSTRING("console.log")); diff --git a/toolkit/xre/nsXREDirProvider.cpp b/toolkit/xre/nsXREDirProvider.cpp index 62b5694e99e8..accdcfe7c0b0 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" @@ -244,9 +245,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(NS_LITERAL_CSTRING("Profiles")); -#endif // We must create the profile directory here if it does not exist. nsresult tmp = EnsureDirectoryExists(file); if (NS_FAILED(tmp)) { @@ -262,9 +260,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(NS_LITERAL_CSTRING("Profiles")); -#endif // We must create the profile directory here if it does not exist. nsresult tmp = EnsureDirectoryExists(file); if (NS_FAILED(tmp)) { @@ -1378,7 +1373,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) { @@ -1388,81 +1383,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(EmptyCString(), 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( + NS_LITERAL_CSTRING("TorBrowser" XPCOM_FILE_PATH_SEPARATOR + "Data" XPCOM_FILE_PATH_SEPARATOR "Browser")); + 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(NS_LITERAL_CSTRING(".cache")); - } - } else { - rv = NS_NewNativeLocalFile(nsDependentCString(homeDir), true, - getter_AddRefs(localDir)); + rv = localDir->AppendNative(NS_LITERAL_CSTRING("Caches")); + 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; @@ -1645,39 +1598,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 @@ -1687,11 +1624,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(); @@ -1699,32 +1631,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 915e8bc7361e..81551a8e3893 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(EmptyString(), 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( + NS_LITERAL_CSTRING("TorBrowser" XPCOM_FILE_PATH_SEPARATOR + "Data" XPCOM_FILE_PATH_SEPARATOR "Browser")); + NS_ENSURE_SUCCESS(rv, rv); + + if (aLocal) { + rv = localDir->AppendNative(NS_LITERAL_CSTRING("Caches")); + 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(NS_LITERAL_CSTRING("Profiles")); - 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-78.5.0esr-10.0-1] Add TorStrings module for localization
by gk@torproject.org 12 Nov '20

12 Nov '20
commit ac00eb3a2ff64d02b2ee502920415b386d41a36c 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 cbb94cf736a0..88f2a55d6f49 100644 --- a/browser/modules/moz.build +++ b/browser/modules/moz.build @@ -154,6 +154,7 @@ EXTRA_JS_MODULES += [ 'TabUnloader.jsm', 'ThemeVariableMap.jsm', 'TopSiteAttribution.jsm', + 'TorStrings.jsm', 'TransientPrefs.jsm', 'webrtcUI.jsm', 'ZoomUI.jsm',
1 0
0 0
[tor-browser/tor-browser-78.5.0esr-10.0-1] Bug 14631: Improve profile access error messages.
by gk@torproject.org 12 Nov '20

12 Nov '20
commit b0c1cc9df5deaae16098cb718170f336ec9bb646 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 | 155 ++++++++++++++++++--- 4 files changed, 207 insertions(+), 23 deletions(-) diff --git a/toolkit/locales/en-US/chrome/mozapps/profile/profileSelection.properties b/toolkit/locales/en-US/chrome/mozapps/profile/profileSelection.properties index 2be092bf4c4b..922b52cb1385 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 a3e50f8c00d3..3f32bd95f9c9 100644 --- a/toolkit/profile/nsToolkitProfileService.cpp +++ b/toolkit/profile/nsToolkitProfileService.cpp @@ -1161,9 +1161,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. @@ -1196,7 +1197,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; } @@ -1290,6 +1292,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); @@ -2079,3 +2088,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) + NS_NAMED_LITERAL_STRING(writeTestFileName, ".parentwritetest"); +#else + NS_NAMED_LITERAL_STRING(writeTestFileName, "parent.writetest"); +#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 f2a238312b95..cfb1964ee1d7 100644 --- a/toolkit/profile/nsToolkitProfileService.h +++ b/toolkit/profile/nsToolkitProfileService.h @@ -15,6 +15,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>> { @@ -79,10 +87,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 4afec36f57bc..3ba04d2b495c 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -1736,6 +1736,91 @@ nsresult LaunchChild(bool aBlankCommandLine) { 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"; @@ -1784,7 +1869,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 @@ -1806,11 +1891,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; @@ -1838,24 +1924,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); + 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()) { @@ -2013,6 +2114,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 @@ -2039,7 +2147,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 @@ -2054,7 +2163,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; @@ -2100,9 +2210,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); @@ -3932,7 +4047,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-78.5.0esr-10.0-1] Bug 13252: Do not store data in the app bundle
by gk@torproject.org 12 Nov '20

12 Nov '20
commit 156a772805905b30989a7d30df06c1e25649cf18 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 | 142 +++++++++++++++++++++++++++++++++ xpcom/io/TorFileUtils.h | 33 ++++++++ xpcom/io/moz.build | 5 ++ xpcom/io/nsAppFileLocationProvider.cpp | 53 +++++------- 7 files changed, 290 insertions(+), 68 deletions(-) diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index 3ba04d2b495c..8e76213e7923 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -1891,6 +1891,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, @@ -1899,17 +1901,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); @@ -1999,7 +2003,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); } @@ -2107,6 +2112,23 @@ static ReturnAbortOnError ShowProfileManager( return LaunchChild(false); } +#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; @@ -3183,6 +3205,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 @@ -4031,7 +4061,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 " @@ -4100,7 +4157,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 @@ -4136,12 +4192,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 accdcfe7c0b0..09f34911d3cb 100644 --- a/toolkit/xre/nsXREDirProvider.cpp +++ b/toolkit/xre/nsXREDirProvider.cpp @@ -46,6 +46,8 @@ #include "mozilla/Telemetry.h" #include "nsPrintfCString.h" +#include "TorFileUtils.h" + #include <stdlib.h> #ifdef XP_WIN @@ -1383,34 +1385,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; - +#if !defined(ANDROID) +#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR + rv = localDir->AppendNative(NS_LITERAL_CSTRING("Browser")); +#else rv = localDir->AppendRelativeNativePath( - NS_LITERAL_CSTRING("TorBrowser" XPCOM_FILE_PATH_SEPARATOR - "Data" XPCOM_FILE_PATH_SEPARATOR "Browser")); + NS_LITERAL_CSTRING("Data" XPCOM_FILE_PATH_SEPARATOR "Browser")); +#endif NS_ENSURE_SUCCESS(rv, rv); +#endif if (aLocal) { rv = localDir->AppendNative(NS_LITERAL_CSTRING("Caches")); @@ -1516,6 +1502,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..bddf8d7bbd95 --- /dev/null +++ b/xpcom/io/TorFileUtils.cpp @@ -0,0 +1,142 @@ +/* -*- 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(NS_LITERAL_CSTRING("TorBrowser-Data")); + 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(EmptyCString(), 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(NS_LITERAL_CSTRING("TorBrowser")); + 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..d5e86abf9685 --- /dev/null +++ b/xpcom/io/TorFileUtils.h @@ -0,0 +1,33 @@ +/* -*- 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 a165b491bc56..b0eb74f4c56d 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 += [ @@ -135,6 +136,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 81551a8e3893..9f95e5cbec2d 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; - } - +#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR + rv = localDir->AppendNative(NS_LITERAL_CSTRING("Browser")); +#else rv = localDir->AppendRelativeNativePath( - NS_LITERAL_CSTRING("TorBrowser" XPCOM_FILE_PATH_SEPARATOR - "Data" XPCOM_FILE_PATH_SEPARATOR "Browser")); + NS_LITERAL_CSTRING("Data" XPCOM_FILE_PATH_SEPARATOR "Browser")); +#endif NS_ENSURE_SUCCESS(rv, rv); if (aLocal) {
1 0
0 0
[tor-browser/tor-browser-78.5.0esr-10.0-1] Bug 18821: Disable libmdns for Android and Desktop
by gk@torproject.org 12 Nov '20

12 Nov '20
commit 80ce46b2db020ba6eda456ada7f818215dd55bbe 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 eaea61af415a..d97b75ddbcf9 100644 --- a/dom/presentation/provider/moz.build +++ b/dom/presentation/provider/moz.build @@ -10,7 +10,6 @@ EXTRA_JS_MODULES += [ 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 05dc75eb9eda..a6fc1a8a559a 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-78.5.0esr-10.0-1] Bug 19273: Avoid JavaScript patching of the external app helper dialog.
by gk@torproject.org 12 Nov '20

12 Nov '20
commit 983804678333863c8503d323c6bba3718bbce771 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 | 202 +++++++++++++++++---- uriloader/exthandler/nsExternalHelperAppService.h | 3 + .../exthandler/nsIExternalHelperAppService.idl | 47 +++++ 3 files changed, 217 insertions(+), 35 deletions(-) diff --git a/uriloader/exthandler/nsExternalHelperAppService.cpp b/uriloader/exthandler/nsExternalHelperAppService.cpp index 4ff7ed2e27cc..0dcc1d3ed6ab 100644 --- a/uriloader/exthandler/nsExternalHelperAppService.cpp +++ b/uriloader/exthandler/nsExternalHelperAppService.cpp @@ -132,6 +132,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 /** @@ -388,6 +391,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 @@ -544,6 +563,111 @@ static const nsDefaultMimeTypeEntry nonDecodableExtensions[] = { {APPLICATION_COMPRESS, "z"}, {APPLICATION_GZIP, "svgz"}}; +////////////////////////////////////////////////////////////////////////////////////////////////////// +// 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; + + nsHandlerInfoAction preferredAction; + mHandlerInfo->GetPreferredAction(&preferredAction); + bool alwaysAsk = true; + mHandlerInfo->GetAlwaysAskBeforeHandling(&alwaysAsk); + + nsresult rv = NS_OK; + // If we are not supposed to ask, and the preferred action is to use + // a helper app or the system default, we just launch the URI. + if (!alwaysAsk && (preferredAction == nsIHandlerInfo::useHelperApp || + preferredAction == nsIHandlerInfo::useSystemDefault)) { + rv = mHandlerInfo->LaunchWithURI(mURI, mBrowsingContext); + // We are not supposed to ask, but when file not found the user most likely + // uninstalled the application which handles the uri so we will continue + // by application chooser dialog. + if (rv != NS_ERROR_FILE_NOT_FOUND) { + return rv; + } + } + + nsCOMPtr<nsIContentDispatchChooser> chooser = + do_CreateInstance("@mozilla.org/content-dispatch-chooser;1", &rv); + NS_ENSURE_SUCCESS(rv, rv); + + return chooser->Ask(mHandlerInfo, mURI, mTriggeringPrincipal, + mBrowsingContext, + nsIContentDispatchChooser::REASON_CANNOT_HANDLE); +} + +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; /** @@ -570,6 +694,9 @@ nsExternalHelperAppService::GetSingleton() { return do_AddRef(sExtHelperAppSvcSingleton); } +////////////////////////////////////////////////////////////////////////////////////////////////////// +// nsExternalHelperAppService definition and implementation +////////////////////////////////////////////////////////////////////////////////////////////////////// NS_IMPL_ISUPPORTS(nsExternalHelperAppService, nsIExternalHelperAppService, nsPIExternalAppLauncher, nsIExternalProtocolService, nsIMIMEService, nsIObserver, nsISupportsWeakReference) @@ -1003,30 +1130,13 @@ nsExternalHelperAppService::LoadURI(nsIURI* aURI, rv = GetProtocolHandlerInfo(scheme, getter_AddRefs(handler)); NS_ENSURE_SUCCESS(rv, rv); - nsHandlerInfoAction preferredAction; - handler->GetPreferredAction(&preferredAction); - bool alwaysAsk = true; - handler->GetAlwaysAskBeforeHandling(&alwaysAsk); - - // if we are not supposed to ask, and the preferred action is to use - // a helper app or the system default, we just launch the URI. - if (!alwaysAsk && (preferredAction == nsIHandlerInfo::useHelperApp || - preferredAction == nsIHandlerInfo::useSystemDefault)) { - rv = handler->LaunchWithURI(uri, aBrowsingContext); - // We are not supposed to ask, but when file not found the user most likely - // uninstalled the application which handles the uri so we will continue - // by application chooser dialog. - if (rv != NS_ERROR_FILE_NOT_FOUND) { - return rv; - } + RefPtr<nsExternalLoadURIHandler> h = new nsExternalLoadURIHandler( + handler, uri, aTriggeringPrincipal, aBrowsingContext); + if (!h) { + return NS_ERROR_OUT_OF_MEMORY; } - nsCOMPtr<nsIContentDispatchChooser> chooser = - do_CreateInstance("@mozilla.org/content-dispatch-chooser;1", &rv); - NS_ENSURE_SUCCESS(rv, rv); - - return chooser->Ask(handler, uri, aTriggeringPrincipal, aBrowsingContext, - nsIContentDispatchChooser::REASON_CANNOT_HANDLE); + return NS_OK; } ////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1171,6 +1281,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) @@ -1532,18 +1643,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) { @@ -1651,6 +1751,29 @@ NS_IMETHODIMP nsExternalAppHandler::OnStartRequest(nsIRequest* request) { MOZ_ASSERT(NS_SUCCEEDED(rv)); } + 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() { + // 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... @@ -1736,6 +1859,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); @@ -1793,6 +1917,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, @@ -2456,7 +2588,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 f2bd67f64ccd..8c2d8817ac7b 100644 --- a/uriloader/exthandler/nsExternalHelperAppService.h +++ b/uriloader/exthandler/nsExternalHelperAppService.h @@ -203,6 +203,7 @@ class nsExternalHelperAppService : public nsIExternalHelperAppService, */ class nsExternalAppHandler final : public nsIStreamListener, public nsIHelperAppLauncher, + public nsIHelperAppWarningLauncher, public nsIBackgroundFileSaverObserver, public nsINamed { public: @@ -210,6 +211,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 @@ -460,6 +462,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 ea8b9b08f3e6..8b58671f7597 100644 --- a/uriloader/exthandler/nsIExternalHelperAppService.idl +++ b/uriloader/exthandler/nsIExternalHelperAppService.idl @@ -182,3 +182,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
[tor-browser/tor-browser-78.5.0esr-10.0-1] Bug 18800: Remove localhost DNS lookup in nsProfileLock.cpp
by gk@torproject.org 12 Nov '20

12 Nov '20
commit 8960524e8cc6d0930d9dd86a1679ae63469cfd97 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 25c4f5a79e56..1942815e3446 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
  • ← Newer
  • 1
  • ...
  • 1299
  • 1300
  • 1301
  • 1302
  • 1303
  • 1304
  • 1305
  • ...
  • 2006
  • Older →

HyperKitty Powered by HyperKitty version 1.3.12.