Add command line switch to start in Tor mode.

This commit implements a command line switch (--tor) that starts Brave
in Tor mode.  This is done by subclassing StartupBrowserCreatorImpl and
implementing a custom Launch method.  If the user provided a --tor
command line flag, the patch switches the profile to Tor mode and then
calls StartupBrowserCreatorImpl's original Launch method.

This commit resolves https://github.com/brave/brave-browser/issues/2105.
This commit is contained in:
Philipp Winter
2021-08-02 15:49:06 -07:00
parent a3e89791c7
commit 6278dabf1e
8 changed files with 146 additions and 8 deletions
+1
View File
@@ -102,6 +102,7 @@ source_set("browser_tests") {
"//brave/browser/tor",
"//brave/browser/ui",
"//brave/common",
"//brave/common:switches",
"//brave/components/ipfs/buildflags",
"//brave/components/tor",
"//brave/components/tor:pref_names",
+9 -8
View File
@@ -46,12 +46,6 @@ void TorProfileManager::SwitchToTorProfile(
ProfileManager::CreateCallback callback) {
Profile* tor_profile =
TorProfileManager::GetInstance().GetTorProfile(original_profile);
tor::TorProfileService* service =
TorProfileServiceFactory::GetForContext(tor_profile);
DCHECK(service);
// TorLauncherFactory relies on OnExecutableReady to launch tor process so we
// need to make sure tor binary is there every time
service->RegisterTorClientUpdater();
profiles::OpenBrowserWindowForProfile(callback, false, false, false,
tor_profile,
Profile::CREATE_STATUS_INITIALIZED);
@@ -73,8 +67,8 @@ TorProfileManager::~TorProfileManager() {
BrowserList::RemoveObserver(this);
}
Profile* TorProfileManager::GetTorProfile(Profile* original_profile) {
Profile* tor_profile = original_profile->GetOffTheRecordProfile(
Profile* TorProfileManager::GetTorProfile(Profile* profile) {
Profile* tor_profile = profile->GetOriginalProfile()->GetOffTheRecordProfile(
Profile::OTRProfileID::CreateFromProfileID(tor::kTorProfileID),
/*create_if_needed=*/true);
@@ -88,6 +82,13 @@ Profile* TorProfileManager::GetTorProfile(Profile* original_profile) {
tor_profile->AddObserver(this);
tor_profiles_[context_id] = tor_profile;
tor::TorProfileService* service =
TorProfileServiceFactory::GetForContext(tor_profile);
DCHECK(service);
// TorLauncherFactory relies on OnExecutableReady to launch tor process so we
// need to make sure tor binary is there every time
service->RegisterTorClientUpdater();
return tor_profile;
}
@@ -4,6 +4,7 @@
// you can obtain one at http://mozilla.org/MPL/2.0/.
#include "base/path_service.h"
#include "base/process/launch.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "brave/browser/brave_ads/ads_service_factory.h"
@@ -11,6 +12,7 @@
#include "brave/browser/tor/tor_profile_manager.h"
#include "brave/browser/tor/tor_profile_service_factory.h"
#include "brave/common/brave_paths.h"
#include "brave/common/brave_switches.h"
#include "brave/components/ipfs/buildflags/buildflags.h"
#include "brave/components/tor/mock_tor_launcher_factory.h"
#include "brave/components/tor/tor_constants.h"
@@ -19,6 +21,7 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
@@ -99,8 +102,36 @@ class TorProfileManagerTest : public InProcessBrowserTest {
MockTorLauncherFactory* GetTorLauncherFactory() {
return &MockTorLauncherFactory::GetInstance();
}
void Relaunch(const base::CommandLine& new_command_line) {
base::LaunchProcess(new_command_line, base::LaunchOptionsForTest());
}
};
// We don't run this test on Mac because the function GetCommandLineForRelaunch
// isn't defined there.
#if !defined(OS_MAC)
IN_PROC_BROWSER_TEST_F(TorProfileManagerTest, LaunchWithTorUrl) {
// We should start with one normal window.
ASSERT_EQ(1u, chrome::GetTabbedBrowserCount(browser()->profile()));
// Run with --tor switch and a URL specified.
base::FilePath test_file_path = ui_test_utils::GetTestFilePath(
base::FilePath(), base::FilePath().AppendASCII("empty.html"));
base::CommandLine new_command_line(GetCommandLineForRelaunch());
new_command_line.AppendSwitch(switches::kTor);
new_command_line.AppendArgPath(test_file_path);
Relaunch(new_command_line);
// There should be one normal and one Tor window now.
Relaunch(new_command_line);
ui_test_utils::WaitForBrowserToOpen();
ASSERT_EQ(2u, chrome::GetTotalBrowserCount());
ASSERT_EQ(1u, chrome::GetTabbedBrowserCount(browser()->profile()));
}
#endif
IN_PROC_BROWSER_TEST_F(TorProfileManagerTest,
SwitchToTorProfileShareBookmarks) {
ProfileManager* profile_manager = g_browser_process->profile_manager();
+2
View File
@@ -251,7 +251,9 @@ source_set("ui") {
"//brave/components/ntp_widget_utils/browser",
"//brave/components/p3a:buildflags",
"//brave/components/sidebar/buildflags",
"//brave/components/tor",
"//brave/components/tor:pref_names",
"//brave/components/tor/buildflags",
"//brave/components/vector_icons",
"//brave/components/webcompat_reporter/browser",
"//brave/components/webcompat_reporter/ui:generated_resources",
@@ -0,0 +1,81 @@
/* Copyright (c) 2021 The Brave Authors. All rights reserved.
* 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 "chrome/browser/ui/startup/startup_browser_creator.h"
#include "brave/common/brave_switches.h"
#include "brave/components/tor/buildflags/buildflags.h"
#include "chrome/browser/ui/startup/startup_browser_creator_impl.h"
#if BUILDFLAG(ENABLE_TOR)
#include "brave/browser/tor/tor_profile_manager.h"
#endif
class BraveStartupBrowserCreatorImpl final : public StartupBrowserCreatorImpl {
public:
BraveStartupBrowserCreatorImpl(const base::FilePath& cur_dir,
const base::CommandLine& command_line,
chrome::startup::IsFirstRun is_first_run);
BraveStartupBrowserCreatorImpl(const base::FilePath& cur_dir,
const base::CommandLine& command_line,
StartupBrowserCreator* browser_creator,
chrome::startup::IsFirstRun is_first_run);
bool Launch(Profile* profile,
const std::vector<GURL>& urls_to_open,
bool process_startup,
std::unique_ptr<LaunchModeRecorder> launch_mode_recorder);
};
BraveStartupBrowserCreatorImpl::BraveStartupBrowserCreatorImpl(
const base::FilePath& cur_dir,
const base::CommandLine& command_line,
chrome::startup::IsFirstRun is_first_run)
: StartupBrowserCreatorImpl(cur_dir, command_line, is_first_run) {}
BraveStartupBrowserCreatorImpl::BraveStartupBrowserCreatorImpl(
const base::FilePath& cur_dir,
const base::CommandLine& command_line,
StartupBrowserCreator* browser_creator,
chrome::startup::IsFirstRun is_first_run)
: StartupBrowserCreatorImpl(cur_dir,
command_line,
browser_creator,
is_first_run) {}
// If the --tor command line flag was provided, switch the profile to Tor mode
// and then call the original Launch method.
//
// Note that if the --tor switch is used together with --silent-launch, Tor
// won't be launched.
bool BraveStartupBrowserCreatorImpl::Launch(
Profile* profile,
const std::vector<GURL>& urls_to_open,
bool process_startup,
std::unique_ptr<LaunchModeRecorder> launch_mode_recorder) {
#if BUILDFLAG(ENABLE_TOR)
if (StartupBrowserCreatorImpl::command_line_.HasSwitch(switches::kTor)) {
LOG(INFO) << "Switching to Tor profile and starting Tor service.";
profile = TorProfileManager::GetInstance().GetTorProfile(profile);
// Call GetURLsFromCommandLine so that if one runs
// brave-browser --tor "? search query"
// the search query is not passed to the default search engine of the
// regular profile.
const std::vector<GURL>& my_urls_to_open =
GetURLsFromCommandLine(command_line_, cur_dir_, profile);
return StartupBrowserCreatorImpl::Launch(profile, my_urls_to_open,
process_startup,
std::move(launch_mode_recorder));
}
#endif
return StartupBrowserCreatorImpl::Launch(
profile, urls_to_open, process_startup, std::move(launch_mode_recorder));
}
#define StartupBrowserCreatorImpl BraveStartupBrowserCreatorImpl
#include "../../../../../../chrome/browser/ui/startup/startup_browser_creator.cc" // NOLINT
#undef StartupBrowserCreatorImpl
@@ -0,0 +1,17 @@
/* Copyright (c) 2021 The Brave Authors. All rights reserved.
* 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 BRAVE_CHROMIUM_SRC_CHROME_BROWSER_UI_STARTUP_STARTUP_BROWSER_CREATOR_IMPL_H_
#define BRAVE_CHROMIUM_SRC_CHROME_BROWSER_UI_STARTUP_STARTUP_BROWSER_CREATOR_IMPL_H_
// Make BraveStartupBrowserCreatorImpl a friend class, to give it access to
// StartupBrowserCreatorImpl's private attributes.
#define browser_creator_ \
browser_creator_; \
friend class BraveStartupBrowserCreatorImpl
#include "../../../../../../chrome/browser/ui/startup/startup_browser_creator_impl.h" // NOLINT
#undef browser_creator_
#endif // BRAVE_CHROMIUM_SRC_CHROME_BROWSER_UI_STARTUP_STARTUP_BROWSER_CREATOR_IMPL_H_
+3
View File
@@ -45,4 +45,7 @@ const char kDisableDnsOverHttps[] = "disable-doh";
// Override update feed url. Only valid on macOS.
const char kUpdateFeedURL[] = "update-feed-url";
// Starts Brave in Tor mode.
const char kTor[] = "tor";
} // namespace switches
+2
View File
@@ -33,6 +33,8 @@ extern const char kComponentUpdateIntervalInSec[];
extern const char kDisableDnsOverHttps[];
extern const char kUpdateFeedURL[];
extern const char kTor[];
} // namespace switches
#endif // BRAVE_COMMON_BRAVE_SWITCHES_H_