tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 0c9de09b15ef84492a7dbd15a6ffe3195558c8a8
parent 5fa4a752781edc1cab5e62deb8752b3dd647358b
Author: Pier Angelo Vendrame <pierov@torproject.org>
Date:   Tue, 31 Jan 2023 11:59:21 +0100

TB 13252: Customize profile management on macOS

On macOS we allow both portable mode and system installation.
However, in the latter case, we customize Firefox's directories to
match the hierarchy we use for the portable mode.

Also, display an informative error message if the TorBrowser-Data
directory cannot be created due to an "access denied" or a
"read only volume" error.

Diffstat:
Mtoolkit/xre/nsXREDirProvider.cpp | 52+++++++++++++++++++++++++++++++++++++++++++++++-----
Mtoolkit/xre/nsXREDirProvider.h | 7+++++++
Mxpcom/io/CocoaFileUtils.mm | 4++++
Mxpcom/io/nsAppFileLocationProvider.cpp | 16++++++++++++++++
4 files changed, 74 insertions(+), 5 deletions(-)

diff --git a/toolkit/xre/nsXREDirProvider.cpp b/toolkit/xre/nsXREDirProvider.cpp @@ -230,7 +230,9 @@ nsresult nsXREDirProvider::GetUserProfilesRootDir(nsIFile** aResult) { nsresult rv = GetUserDataDirectory(getter_AddRefs(file), false); if (NS_SUCCEEDED(rv)) { -#if !defined(XP_UNIX) || defined(XP_MACOSX) + // For some reason, we have decided not to append "Profiles" in Tor Browser. + // So, let's keep removing it, or we should somehow migrate the profile. +#if !defined(TOR_BROWSER) && (!defined(XP_UNIX) || defined(XP_MACOSX)) rv = file->AppendNative("Profiles"_ns); #endif // We must create the profile directory here if it does not exist. @@ -276,7 +278,7 @@ nsresult nsXREDirProvider::GetUserProfilesLocalDir(nsIFile** aResult) { nsresult rv = GetUserDataDirectory(getter_AddRefs(file), true); if (NS_SUCCEEDED(rv)) { -#if !defined(XP_UNIX) || defined(XP_MACOSX) +#if !defined(TOR_BROWSER) && (!defined(XP_UNIX) || defined(XP_MACOSX)) rv = file->AppendNative("Profiles"_ns); #endif // We must create the profile directory here if it does not exist. @@ -1317,21 +1319,39 @@ nsresult nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile, #if defined(XP_MACOSX) FSRef fsRef; +# if defined(TOR_BROWSER) + OSType folderType = kApplicationSupportFolderType; +# else OSType folderType; if (aLocal) { folderType = kCachedDataFolderType; } else { -# ifdef MOZ_THUNDERBIRD +# ifdef MOZ_THUNDERBIRD folderType = kDomainLibraryFolderType; -# else +# else folderType = kApplicationSupportFolderType; -# endif +# endif } +# endif OSErr err = ::FSFindFolder(kUserDomain, folderType, kCreateFolder, &fsRef); NS_ENSURE_FALSE(err, NS_ERROR_FAILURE); nsCOMPtr<nsILocalFileMac> dirFileMac; MOZ_TRY(NS_NewLocalFileWithFSRef(&fsRef, getter_AddRefs(dirFileMac))); + +# if defined(TOR_BROWSER) + { + nsresult rv = dirFileMac->AppendNative("TorBrowser-Data"_ns); + NS_ENSURE_SUCCESS(rv, rv); + rv = dirFileMac->AppendNative("Browser"_ns); + NS_ENSURE_SUCCESS(rv, rv); + if (aLocal) { + rv = dirFileMac->AppendNative("Caches"_ns); + NS_ENSURE_SUCCESS(rv, rv); + } + } +# endif + localDir = dirFileMac.forget(); #elif defined(XP_IOS) nsAutoCString userDir; @@ -1769,6 +1789,9 @@ nsresult nsXREDirProvider::AppendProfilePath(nsIFile* aFile, bool aLocal) { nsresult rv = NS_OK; #if defined(XP_MACOSX) +# ifndef TOR_BROWSER + // For Tor Browser we already prepare the data directory as we need it, even + // when we are running a system install. if (!profile.IsEmpty()) { rv = AppendProfileString(aFile, profile.get()); } else { @@ -1778,6 +1801,7 @@ nsresult nsXREDirProvider::AppendProfilePath(nsIFile* aFile, bool aLocal) { rv = aFile->AppendNative(appName); } NS_ENSURE_SUCCESS(rv, rv); +# endif #elif defined(XP_WIN) if (!profile.IsEmpty()) { @@ -1868,3 +1892,21 @@ nsresult nsXREDirProvider::AppendProfileString(nsIFile* aFile, return NS_OK; } + +nsresult nsXREDirProvider::GetTorBrowserUserDataDir(nsIFile** aFile) { +#ifdef ANDROID + // We expect this function not to be called on Android. + // But, for sake of completeness, we handle also this case. + const char* homeDir = getenv("HOME"); + if (!homeDir || !*homeDir) { + return NS_ERROR_FAILURE; + } + return NS_NewNativeLocalFile(nsDependentCString(homeDir), aFile); +#endif + + NS_ENSURE_ARG_POINTER(aFile); + nsCOMPtr<nsIFile> dataDir; + nsresult rv = GetUserDataDirectoryHome(getter_AddRefs(dataDir), false); + NS_ENSURE_SUCCESS(rv, rv); + return dataDir->GetParent(aFile); +} diff --git a/toolkit/xre/nsXREDirProvider.h b/toolkit/xre/nsXREDirProvider.h @@ -132,6 +132,13 @@ class nsXREDirProvider final : public nsIDirectoryServiceProvider2, nsresult GetProfileDir(nsIFile** aResult); /** + * Get the Tor Browser user data directory. + * We take for granted that for Tor Browser we can take the parent directory + * of the one returned by GetUserDataDirectoryHome (with aLocal = false). + */ + nsresult GetTorBrowserUserDataDir(nsIFile** aFile); + + /** * Test only methods used by XREAppDir gtests to reset the values of * gDataDirProfileLocal and gDataDirProfile */ diff --git a/xpcom/io/CocoaFileUtils.mm b/xpcom/io/CocoaFileUtils.mm @@ -320,8 +320,12 @@ void CopyQuarantineReferrerUrl(const CFStringRef aFilePath, CFTypeRefPtr<CFURLRef> GetProductDirectory(bool aLocal) { nsAutoreleasePool localPool; +#if defined(TOR_BROWSER) + NSSearchPathDirectory folderType = NSApplicationSupportDirectory; +#else NSSearchPathDirectory folderType = aLocal ? NSCachesDirectory : NSLibraryDirectory; +#endif NSFileManager* manager = [NSFileManager defaultManager]; return CFTypeRefPtr<CFURLRef>::WrapUnderGetRule((__bridge CFURLRef)[[manager URLsForDirectory:folderType diff --git a/xpcom/io/nsAppFileLocationProvider.cpp b/xpcom/io/nsAppFileLocationProvider.cpp @@ -308,6 +308,17 @@ nsresult nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile, return rv; } localDir = localDirMac.forget(); + +# if defined(TOR_BROWSER) + rv = localDir->AppendNative("TorBrowser-Data"_ns); + NS_ENSURE_SUCCESS(rv, rv); + rv = localDir->AppendNative("Browser"_ns); + NS_ENSURE_SUCCESS(rv, rv); + if (aLocal) { + rv = localDir->AppendNative("Caches"_ns); + NS_ENSURE_SUCCESS(rv, rv); + } +# endif #elif defined(XP_WIN) nsCOMPtr<nsIProperties> directoryService = do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv); @@ -340,6 +351,7 @@ nsresult nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile, # error dont_know_how_to_get_product_dir_on_your_platform #endif +#if !defined(TOR_BROWSER) #if defined(MOZ_WIDGET_GTK) bool legacyExists = nsXREDirProvider::LegacyHomeExists(nullptr); if (legacyExists || nsXREDirProvider::IsForceLegacyHome()) { @@ -362,6 +374,7 @@ nsresult nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile, if (NS_FAILED(rv)) { return rv; } +#endif rv = localDir->Exists(&exists); if (NS_SUCCEEDED(rv) && !exists) { @@ -402,10 +415,13 @@ nsresult nsAppFileLocationProvider::GetDefaultUserProfileRoot( #if defined(MOZ_WIDGET_COCOA) || defined(XP_WIN) // These 3 platforms share this part of the path - do them as one +# ifndef TOR_BROWSER + // Legacy: we do not use "Profiles" on Tor Browser. rv = localDir->AppendRelativeNativePath("Profiles"_ns); if (NS_FAILED(rv)) { return rv; } +# endif bool exists; rv = localDir->Exists(&exists);