commit 38e31a62d48dd8ea8bee02673b7050338fc1c22a Author: Kathy Brade brade@pearlcrescent.com Date: Mon Feb 29 16:55:06 2016 -0500
fixup! Bug #4234: Use the Firefox Update Process for Tor Browser.
When built with --enable-tor-browser-data-outside-app-dir, account for the new Mac OS directory structure (see bug #13252). Many of the updater changes we made earlier are no longer needed.
Also, fix a JS warning inside toolkit/mozapps/update/nsUpdateService.js and improve startup time logging of update status. --- config/createprecomplete.py | 4 ++ toolkit/mozapps/update/nsUpdateService.js | 3 +- toolkit/mozapps/update/updater/updater.cpp | 18 ++++-- toolkit/xre/nsUpdateDriver.cpp | 36 +++++++++++- toolkit/xre/nsXREDirProvider.cpp | 14 +++++ tools/update-packaging/common.sh | 4 ++ tools/update-packaging/make_full_update.sh | 21 +++++-- tools/update-packaging/make_incremental_update.sh | 71 ++++++++++++++--------- 8 files changed, 128 insertions(+), 43 deletions(-)
diff --git a/config/createprecomplete.py b/config/createprecomplete.py index 48cba96..be571be 100644 --- a/config/createprecomplete.py +++ b/config/createprecomplete.py @@ -10,6 +10,10 @@ import sys import os
+# TODO When TOR_BROWSER_DATA_OUTSIDE_APP_DIR is used on all platforms, +# we should remove all lines in this file that contain: +# TorBrowser/Data + def get_build_entries(root_path): """ Iterates through the root_path, creating a list for each file and directory. Excludes any file paths ending with channel-prefs.js. diff --git a/toolkit/mozapps/update/nsUpdateService.js b/toolkit/mozapps/update/nsUpdateService.js index e720ae4..2d443a7 100644 --- a/toolkit/mozapps/update/nsUpdateService.js +++ b/toolkit/mozapps/update/nsUpdateService.js @@ -1025,7 +1025,7 @@ function getUpdatesDirInApplyToDir() { #endif dir.append(UPDATED_DIR); #ifdef XP_MACOSX -#ifdef TOR_BROWSER_UPDATE +#if defined(TOR_BROWSER_UPDATE) && !defined(TOR_BROWSER_DATA_OUTSIDE_APP_DIR) dir.append("TorBrowser"); dir.append("UpdateInfo"); #else @@ -4051,6 +4051,7 @@ Downloader.prototype = { createInstance(Ci.nsIFileInputStream); fileStream.init(destination, FileUtils.MODE_RDONLY, FileUtils.PERMS_FILE, 0);
+ let digest; try { var hash = Cc["@mozilla.org/security/hash;1"]. createInstance(Ci.nsICryptoHash); diff --git a/toolkit/mozapps/update/updater/updater.cpp b/toolkit/mozapps/update/updater/updater.cpp index 31a5dac..e089a2a 100644 --- a/toolkit/mozapps/update/updater/updater.cpp +++ b/toolkit/mozapps/update/updater/updater.cpp @@ -2281,7 +2281,7 @@ static int CopyInstallDirToDestDir() { // These files should not be copied over to the updated app -#ifdef TOR_BROWSER_UPDATE +#if defined(TOR_BROWSER_UPDATE) && !defined(TOR_BROWSER_DATA_OUTSIDE_APP_DIR) #ifdef XP_WIN #define SKIPLIST_COUNT 6 #else @@ -2297,7 +2297,7 @@ CopyInstallDirToDestDir() #endif #endif copy_recursive_skiplist<SKIPLIST_COUNT> skiplist; -#ifdef TOR_BROWSER_UPDATE +#if defined(TOR_BROWSER_UPDATE) && !defined(TOR_BROWSER_DATA_OUTSIDE_APP_DIR) #ifdef XP_MACOSX skiplist.append(0, gInstallDirPath, NS_T("Updated.app")); skiplist.append(1, gInstallDirPath, NS_T("TorBrowser/UpdateInfo/updates/0")); @@ -2312,7 +2312,7 @@ CopyInstallDirToDestDir() #endif #endif
-#ifdef TOR_BROWSER_UPDATE +#if defined(TOR_BROWSER_UPDATE) && !defined(TOR_BROWSER_DATA_OUTSIDE_APP_DIR) #ifdef XP_WIN skiplist.append(SKIPLIST_COUNT - 3, gInstallDirPath, NS_T("TorBrowser/Data/Browser/profile.default/parent.lock")); @@ -2454,7 +2454,7 @@ ProcessReplaceRequest() // On OS X, we we need to remove the staging directory after its Contents // directory has been moved. NS_tchar updatedAppDir[MAXPATHLEN]; -#ifdef TOR_BROWSER_UPDATE +#if defined(TOR_BROWSER_UPDATE) && !defined(TOR_BROWSER_DATA_OUTSIDE_APP_DIR) NS_tsnprintf(updatedAppDir, sizeof(updatedAppDir)/sizeof(updatedAppDir[0]), NS_T("%s/Updated.app"), gInstallDirPath); // For Tor Browser on OS X, we also need to copy everything else that is inside Updated.app. @@ -3229,6 +3229,15 @@ int NS_main(int argc, NS_tchar **argv) if (!useService && !noServiceFallback && updateLockFileHandle == INVALID_HANDLE_VALUE) { #ifdef TOR_BROWSER_UPDATE +#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR + // Because the TorBrowser-Data directory that contains the user's + // profile is a sibling of the Tor Browser installation directory, + // the user probably has permission to apply updates. Therefore, to + // avoid potential security issues such as CVE-2015-0833, do not + // attempt to elevate privileges. Instead, write a "failed" message + // to the update status file (this function will return immediately + // after the CloseHandle(elevatedFileHandle) call below). +#else // Because the user profile is contained within the Tor Browser // installation directory, the user almost certainly has permission to // apply updates. Therefore, to avoid potential security issues such @@ -3236,6 +3245,7 @@ int NS_main(int argc, NS_tchar **argv) // write a "failed" message to the update status file (this function // will return immediately after the CloseHandle(elevatedFileHandle) // call below). +#endif WriteStatusFile(WRITE_ERROR_ACCESS_DENIED); #else SHELLEXECUTEINFO sinfo; diff --git a/toolkit/xre/nsUpdateDriver.cpp b/toolkit/xre/nsUpdateDriver.cpp index 085f439..9f61652 100644 --- a/toolkit/xre/nsUpdateDriver.cpp +++ b/toolkit/xre/nsUpdateDriver.cpp @@ -267,6 +267,33 @@ typedef enum { eAppliedService } UpdateStatus;
+#ifdef DEBUG +static const char * +UpdateStatusToString(UpdateStatus aStatus) +{ + const char *rv = "unknown"; + switch (aStatus) { + case eNoUpdateAction: + rv = "NoUpdateAction"; + break; + case ePendingUpdate: + rv = "PendingUpdate"; + break; + case ePendingService: + rv = "PendingService"; + break; + case eAppliedUpdate: + rv = "AppliedUpdate"; + break; + case eAppliedService: + rv = "AppliedService"; + break; + } + + return rv; +} +#endif + /** * Returns a value indicating what needs to be done in order to handle an update. * @@ -345,6 +372,7 @@ IsOlderVersion(nsIFile *versionFile, const char *appVersion) return false; }
+#ifndef TOR_BROWSER_DATA_OUTSIDE_APP_DIR #if defined(TOR_BROWSER_UPDATE) && defined(XP_MACOSX) static nsresult GetUpdateDirFromAppDir(nsIFile *aAppDir, nsIFile* *aResult) @@ -369,6 +397,7 @@ GetUpdateDirFromAppDir(nsIFile *aAppDir, nsIFile* *aResult) return NS_OK; } #endif +#endif
#if defined(XP_WIN) && defined(MOZ_METRO) static bool @@ -605,7 +634,7 @@ SwitchToUpdatedApp(nsIFile *greDir, nsIFile *updateDir, nsAutoCString applyToDir; nsCOMPtr<nsIFile> updatedDir; #ifdef XP_MACOSX -#ifdef TOR_BROWSER_UPDATE +#if defined(TOR_BROWSER_UPDATE) && !defined(TOR_BROWSER_DATA_OUTSIDE_APP_DIR) rv = GetUpdateDirFromAppDir(appDir, getter_AddRefs(updatedDir)); if (NS_FAILED(rv)) { #else @@ -899,7 +928,7 @@ ApplyUpdate(nsIFile *greDir, nsIFile *updateDir, nsIFile *statusFile, applyToDir.Assign(installDirPath); } else { #ifdef XP_MACOSX -#ifdef TOR_BROWSER_UPDATE +#if defined(TOR_BROWSER_UPDATE) && !defined(TOR_BROWSER_DATA_OUTSIDE_APP_DIR) rv = GetUpdateDirFromAppDir(appDir, getter_AddRefs(updatedDir)); if (NS_FAILED(rv)) { #else @@ -1160,7 +1189,8 @@ ProcessUpdates(nsIFile *greDir, nsIFile *appDir, nsIFile *updRootDir, nsCOMPtr<nsIFile> statusFile; UpdateStatus status = GetUpdateStatus(updatesDir, statusFile); #ifdef DEBUG - printf("ProcessUpdates status: %d\n", status); + printf("ProcessUpdates status: %s (%d)\n", + UpdateStatusToString(status), status); updatesDir->GetNativePath(path); printf("ProcessUpdates updatesDir: %s\n", path.get()); #endif diff --git a/toolkit/xre/nsXREDirProvider.cpp b/toolkit/xre/nsXREDirProvider.cpp index ab652a4..675039e 100644 --- a/toolkit/xre/nsXREDirProvider.cpp +++ b/toolkit/xre/nsXREDirProvider.cpp @@ -1033,6 +1033,19 @@ nsXREDirProvider::GetUpdateRootDir(nsIFile* *aResult)
#ifdef XP_MACOSX #ifdef TOR_BROWSER_UPDATE +#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR + // For Tor Browser, we cannot store update history, etc. under the user's + // home directory. Instead, we place it under + // Tor Browser.app/../TorBrowser-Data/UpdateInfo/ + nsCOMPtr<nsIFile> appRootDir; + rv = GetAppRootDir(getter_AddRefs(appRootDir)); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr<nsIFile> localDir; + rv = appRootDir->GetParent(getter_AddRefs(localDir)); + NS_ENSURE_SUCCESS(rv, rv); + rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("TorBrowser-Data" + XPCOM_FILE_PATH_SEPARATOR "UpdateInfo")); +#else // For Tor Browser, we cannot store update history, etc. under the user's home directory. // Instead, we place it under Tor Browser.app/TorBrowser/UpdateInfo/ nsCOMPtr<nsIFile> localDir; @@ -1041,6 +1054,7 @@ nsXREDirProvider::GetUpdateRootDir(nsIFile* *aResult) rv = localDir->AppendNative(NS_LITERAL_CSTRING("TorBrowser")); NS_ENSURE_SUCCESS(rv, rv); rv = localDir->AppendNative(NS_LITERAL_CSTRING("UpdateInfo")); +#endif NS_ENSURE_SUCCESS(rv, rv); #else nsCOMPtr<nsIFile> appRootDirFile; diff --git a/tools/update-packaging/common.sh b/tools/update-packaging/common.sh index 6733679..5af9e27 100755 --- a/tools/update-packaging/common.sh +++ b/tools/update-packaging/common.sh @@ -8,6 +8,10 @@ # Author: Darin Fisher #
+# TODO When TOR_BROWSER_DATA_OUTSIDE_APP_DIR is used on all platforms, +# we should remove all lines in this file that contain: +# TorBrowser/Data + # ----------------------------------------------------------------------------- QUIET=0
diff --git a/tools/update-packaging/make_full_update.sh b/tools/update-packaging/make_full_update.sh index 3578ae4..f0bd7f6 100755 --- a/tools/update-packaging/make_full_update.sh +++ b/tools/update-packaging/make_full_update.sh @@ -10,12 +10,6 @@
. $(dirname "$0")/common.sh
-# TODO: it would be better to pass this as a command line option. -# Make sure we delete the pre 5.1.0 HTTPS Everywhere as well in case it -# exists. The extension ID got changed with the version bump to 5.1.0. -ext_path='TorBrowser/Data/Browser/profile.default/extensions' -directories_to_remove="$ext_path/https-everywhere@eff.org $ext_path/https-everywhere-eff@eff.org" - # -----------------------------------------------------------------------------
print_usage() { @@ -77,6 +71,18 @@ fi list_files files list_symlinks symlinks symlink_targets
+# TODO When TOR_BROWSER_DATA_OUTSIDE_APP_DIR is used on all platforms, +# we should remove the following lines: +# Make sure we delete the pre 5.1.0 HTTPS Everywhere as well in case it +# exists. The extension ID got changed with the version bump to 5.1.0. +ext_path='TorBrowser/Data/Browser/profile.default/extensions' +if [ -d "$ext_dir" ]; then + directories_to_remove="$ext_path/https-everywhere@eff.org $ext_path/https-everywhere-eff@eff.org" +else + directories_to_remove="" +fi +# END TOR_BROWSER_DATA_OUTSIDE_APP_DIR removal + popd
# Add the type of update to the beginning of the update manifests. @@ -88,6 +94,8 @@ notice " type complete" echo "type "complete"" >> "$updatemanifestv2" echo "type "complete"" >> "$updatemanifestv3"
+# TODO When TOR_BROWSER_DATA_OUTSIDE_APP_DIR is used on all platforms, +# we should remove the following lines: # If removal of any old, existing directories is desired, emit the appropriate # rmrfdir commands. notice "" @@ -100,6 +108,7 @@ for dir_to_remove in $directories_to_remove; do echo "rmrfdir "$dir_to_remove"" >> "$updatemanifestv2" echo "rmrfdir "$dir_to_remove"" >> "$updatemanifestv3" done +# END TOR_BROWSER_DATA_OUTSIDE_APP_DIR removal
notice "" notice "Adding file add instructions to update manifests" diff --git a/tools/update-packaging/make_incremental_update.sh b/tools/update-packaging/make_incremental_update.sh index c803809..15af172 100755 --- a/tools/update-packaging/make_incremental_update.sh +++ b/tools/update-packaging/make_incremental_update.sh @@ -63,6 +63,8 @@ check_for_forced_update() { return 0; fi
+# TODO When TOR_BROWSER_DATA_OUTSIDE_APP_DIR is used on all platforms, +# we should remove the following lines: # If the file in the skip list ends with /*, do a prefix match. # This allows TorBrowser/Data/Browser/profile.default/extensions/https-everywhere-eff@eff.org/* # to be used to force all HTTPS Everywhere files to be updated. @@ -74,6 +76,7 @@ check_for_forced_update() { return 0; fi fi +# END TOR_BROWSER_DATA_OUTSIDE_APP_DIR removal done ## 'false'... because this is bash. Oh yay! return 1; @@ -84,6 +87,8 @@ if [ $# = 0 ]; then exit 1 fi
+# Firefox uses requested_forced_updates='Contents/MacOS/firefox' due to +# 770996 but in Tor Browser we do not need that fix. requested_forced_updates="" directories_to_remove=""
@@ -120,40 +125,45 @@ updatemanifestv2="$workdir/updatev2.manifest" updatemanifestv3="$workdir/updatev3.manifest" archivefiles="updatev2.manifest updatev3.manifest"
+# TODO When TOR_BROWSER_DATA_OUTSIDE_APP_DIR is used on all platforms, +# we should remove the following lines: # If the NoScript or HTTPS Everywhere extensions have changed between # releases, add them to the "force updates" list. ext_path='TorBrowser/Data/Browser/profile.default/extensions' -https_everywhere='https-everywhere-eff@eff.org' -noscript='{73a6fe31-595d-460b-a920-fcc0f8843232}.xpi' - -# NoScript is a packed extension, so we simply compare the old and the new -# .xpi files. -noscript_path="$ext_path/$noscript" -diff -a "$olddir/$noscript_path" "$newdir/$noscript_path" > /dev/null -rc=$? -if [ $rc -gt 1 ]; then - notice "Unexpected exit $rc from $noscript_path diff command" - exit 2 -elif [ $rc -eq 1 ]; then - requested_forced_updates="$requested_forced_updates $noscript_path" -fi +if [ -d "$newdir/$ext_path" ]; then + https_everywhere='https-everywhere-eff@eff.org' + noscript='{73a6fe31-595d-460b-a920-fcc0f8843232}.xpi' + + # NoScript is a packed extension, so we simply compare the old and the new + # .xpi files. + noscript_path="$ext_path/$noscript" + diff -a "$olddir/$noscript_path" "$newdir/$noscript_path" > /dev/null + rc=$? + if [ $rc -gt 1 ]; then + notice "Unexpected exit $rc from $noscript_path diff command" + exit 2 + elif [ $rc -eq 1 ]; then + requested_forced_updates="$requested_forced_updates $noscript_path" + fi
-# HTTPS Everywhere is an unpacked extension, so we need to determine if any of -# the unpacked files have changed. Since that is messy, we simply compare the -# old extension's install.rdf file to the new one. -https_everywhere_install_rdf="$ext_path/$https_everywhere/install.rdf" -diff "$olddir/$https_everywhere_install_rdf" \ - "$newdir/$https_everywhere_install_rdf" > /dev/null -rc=$? -if [ $rc -gt 1 -a -e "$olddir/$https_everywhere_install_rdf" ]; then - notice "Unexpected exit $rc from $https_everywhere_install_rdf diff command" - exit 2 -elif [ $rc -ge 1 ]; then - requested_forced_updates="$requested_forced_updates $ext_path/$https_everywhere/*" - # Make sure we delete the pre 5.1.0 HTTPS Everywhere as well in case it - # exists. The extension ID got changed with the version bump to 5.1.0. - directories_to_remove="$directories_to_remove $ext_path/https-everywhere@eff.org $ext_path/$https_everywhere" + # HTTPS Everywhere is an unpacked extension, so we need to determine if any of + # the unpacked files have changed. Since that is messy, we simply compare the + # old extension's install.rdf file to the new one. + https_everywhere_install_rdf="$ext_path/$https_everywhere/install.rdf" + diff "$olddir/$https_everywhere_install_rdf" \ + "$newdir/$https_everywhere_install_rdf" > /dev/null + rc=$? + if [ $rc -gt 1 -a -e "$olddir/$https_everywhere_install_rdf" ]; then + notice "Unexpected exit $rc from $https_everywhere_install_rdf diff command" + exit 2 + elif [ $rc -ge 1 ]; then + requested_forced_updates="$requested_forced_updates $ext_path/$https_everywhere/*" + # Make sure we delete the pre 5.1.0 HTTPS Everywhere as well in case it + # exists. The extension ID got changed with the version bump to 5.1.0. + directories_to_remove="$directories_to_remove $ext_path/https-everywhere@eff.org $ext_path/$https_everywhere" + fi fi +# END TOR_BROWSER_DATA_OUTSIDE_APP_DIR removal
mkdir -p "$workdir"
@@ -196,6 +206,8 @@ notice " type partial" echo "type "partial"" >> "$updatemanifestv2" echo "type "partial"" >> "$updatemanifestv3"
+# TODO When TOR_BROWSER_DATA_OUTSIDE_APP_DIR is used on all platforms, +# we should remove the following lines: # If removal of any old, existing directories is desired, emit the appropriate # rmrfdir commands. notice "" @@ -208,6 +220,7 @@ for dir_to_remove in $directories_to_remove; do echo "rmrfdir "$dir_to_remove"" >> "$updatemanifestv2" echo "rmrfdir "$dir_to_remove"" >> "$updatemanifestv3" done +# END TOR_BROWSER_DATA_OUTSIDE_APP_DIR removal
notice "" notice "Adding file patch and add instructions to update manifests"