diff --git a/BUILD.gn b/BUILD.gn index 6b0b0eb2a9..1d200201d1 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -19,6 +19,7 @@ import("//tools/v8_context_snapshot/v8_context_snapshot.gni") import("//v8/gni/v8.gni") import("//third_party/icu/config.gni") import("//media/cdm/library_cdm/cdm_paths.gni") +import("//mojo/public/tools/bindings/mojom.gni") import("//electron/build/config.gni") group("electron") { @@ -55,7 +56,10 @@ group("electron") { } if (use_aura && (is_win || is_linux)) { - data_deps += [ "app:service_manifests" ] + data_deps += [ + "//chrome/app:service_manifests", + "//chrome/app:chrome_renderer_manifest", + ] } } @@ -84,7 +88,7 @@ grit("brave_resources") { ] deps = [ - "app:brave_content_manifest_overlays", + "//chrome/app:chrome_content_manifest_overlays", "//chrome/browser/safe_browsing", ] @@ -239,6 +243,7 @@ source_set("common") { "//base", "//components/url_formatter", "//content/public/child", + ":mojo_bindings", ] if (enable_extensions) { @@ -246,6 +251,17 @@ source_set("common") { "brave/common/extensions/api", ] } + +} + +mojom("mojo_bindings") { + sources = [ + "brave/common/tor/tor.mojom", + ] + + public_deps = [ + "//mojo/public/mojom/base", + ] } source_set("utility") { @@ -266,6 +282,7 @@ source_set("utility") { "//components/cookie_config", "//services/proxy_resolver:lib", "//third_party/protobuf:protobuf_lite", + ":tor", ] if (use_glib) { @@ -291,6 +308,19 @@ source_set("utility") { ] } +source_set("tor") { + sources = [ + "brave/utility/tor/tor_launcher_impl.cc", + "brave/utility/tor/tor_launcher_impl.h", + "brave/utility/tor/tor_service.cc", + "brave/utility/tor/tor_service.h", + ] + + deps = [ + ":mojo_bindings", + ] +} + source_set("renderer") { public_configs = [ "build:electron_config", diff --git a/app/BUILD.gn b/app/BUILD.gn index 210a921dc6..73854a269c 100644 --- a/app/BUILD.gn +++ b/app/BUILD.gn @@ -6,33 +6,9 @@ import("//build/config/ui.gni") import("//tools/grit/grit_rule.gni") import("//services/service_manager/public/service_manifest.gni") -service_manifest("brave_content_packaged_services_manifest_overlay") { - source = "//chrome/browser/chrome_content_packaged_services_manifest_overlay.json" - packaged_services = [ - "//chrome/utility:profile_import_manifest", - ] -} - -group("brave_content_manifest_overlays") { - deps = [ - "//chrome/app:chrome_content_manifest_overlays", - ":brave_content_packaged_services_manifest_overlay", - ] -} - -if (use_aura) { - service_manifest("brave_content_packaged_services_manifest") { - source_manifest = "//content/public/app:packaged_services_manifest" - overlays = [ ":brave_content_packaged_services_manifest_overlay" ] - } - - group("service_manifests") { - data_deps = [ - "//chrome/app:service_manifests", - "//chrome/app:chrome_renderer_manifest", - ":brave_content_packaged_services_manifest_overlay", - ] - } +service_manifest("tor_launcher_manifest") { + name = "tor_launcher" + source = "//electron//brave/utility/tor/tor_manifest.json" } grit("brave_strings") { diff --git a/app/brave_strings.grd b/app/brave_strings.grd index c876b789a2..c2c3c8f200 100644 --- a/app/brave_strings.grd +++ b/app/brave_strings.grd @@ -20,6 +20,9 @@ Brave. These strings will be translated for each locale that Brave supports --> Brave + + Tor Launcher + diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index db0a260094..9711c7489c 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -40,6 +40,7 @@ #include "base/time/time.h" #include "brave/browser/brave_content_browser_client.h" #include "brave/browser/brave_permission_manager.h" +#include "brave/browser/tor/tor_launcher_factory.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/pref_names.h" @@ -177,6 +178,19 @@ struct Converter { } }; +template<> +struct Converter { + static v8::Local ToV8( + v8::Isolate* isolate, brave::TorLauncherFactory::TorProcessState val) { + if (val == brave::TorLauncherFactory::TorProcessState::LAUNCH_SUCCEEDED) + return mate::StringToV8(isolate, "launch-succeeded"); + else if (val == brave::TorLauncherFactory::TorProcessState::LAUNCH_FAILED) + return mate::StringToV8(isolate, "launch-failed"); + else if (val == brave::TorLauncherFactory::TorProcessState::CRASHED) + return mate::StringToV8(isolate, "crashed"); + } +}; + } // namespace mate namespace atom { @@ -215,14 +229,14 @@ class ResolveProxyHelper { const GURL& url) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - net::ProxyResolutionService* proxy_service = + net::ProxyResolutionService* proxy_resolution_service = context_getter->GetURLRequestContext()->proxy_resolution_service(); net::CompletionCallback completion_callback = base::Bind(&ResolveProxyHelper::OnResolveProxyCompleted, base::Unretained(this)); // Start the request. - int result = proxy_service->ResolveProxy( + int result = proxy_resolution_service->ResolveProxy( url, "GET", &proxy_info_, completion_callback, &pac_req_, nullptr, net::NetLogWithSource()); @@ -293,20 +307,6 @@ void DoCacheActionInIO( on_get_backend.Run(net::OK); } -void SetProxyInIO(scoped_refptr getter, - const net::ProxyConfig& config, - const base::Closure& callback) { - auto proxy_service = - getter->GetURLRequestContext()->proxy_resolution_service(); - proxy_service->ResetConfigService( - base::WrapUnique(new net::ProxyConfigServiceFixed( - net::ProxyConfigWithAnnotation(config, NO_TRAFFIC_ANNOTATION_YET)))); - // Refetches and applies the new pac script if provided. - proxy_service->ForceReloadProxyConfig(); - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, callback); -} - void SetCertVerifyProcInIO( const scoped_refptr& context_getter, const AtomCertVerifier::VerifyProc& proc) { @@ -464,10 +464,24 @@ void Session::FlushStorageData() { storage_partition->Flush(); } +void SetProxyInIO(scoped_refptr getter, + const net::ProxyConfig& config, + const base::Closure& callback) { + auto proxy_resolution_service = + getter->GetURLRequestContext()->proxy_resolution_service(); + proxy_resolution_service->ResetConfigService(base::WrapUnique( + new net::ProxyConfigServiceFixed( + net::ProxyConfigWithAnnotation(config, NO_TRAFFIC_ANNOTATION_YET)))); + // Refetches and applies the new pac script if provided. + proxy_resolution_service->ForceReloadProxyConfig(); + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, callback); +} + void Session::SetProxy(const net::ProxyConfig& config, const base::Closure& callback) { BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, - base::Bind(&SetProxyInIO, request_context_getter_, config, callback)); + base::Bind(&SetProxyInIO, request_context_getter_, config, callback)); } void Session::SetDownloadPath(const base::FilePath& path) { @@ -601,6 +615,62 @@ bool Session::Equal(Session* session) const { #endif } +bool Session::IsOffTheRecord() const { + brave::BraveBrowserContext* brave_browser_context = + brave::BraveBrowserContext::FromBrowserContext(profile_); + if (brave_browser_context->IsOffTheRecord()) + return true; + if (brave_browser_context->IsIsolatedStorage()) + return true; + return false; +} + +void Session::SetTorNewIdentity(const GURL& url, + const base::Closure& callback) const { + brave::BraveBrowserContext* brave_browser_context = + brave::BraveBrowserContext::FromBrowserContext(profile_); + if (!brave_browser_context->IsTorBrowserContext()) { + LOG(ERROR) << __func__ << " only available for tor browser context"; + return; + } + brave_browser_context->SetTorNewIdentity(url, callback); +} + +void Session::RelaunchTor() const { + brave::BraveBrowserContext* brave_browser_context = + brave::BraveBrowserContext::FromBrowserContext(profile_); + if (!brave_browser_context->IsTorBrowserContext()) { + LOG(ERROR) << __func__ << " only available for tor browser context"; + return; + } + brave_browser_context->RelaunchTor(); +} + +int64_t Session::GetTorPid() const { + brave::BraveBrowserContext* brave_browser_context = + brave::BraveBrowserContext::FromBrowserContext(profile_); + if (!brave_browser_context->IsTorBrowserContext()) { + LOG(ERROR) << __func__ << " only available for tor browser context"; + return -1; + } + return brave_browser_context->GetTorPid(); +} + +void Session::SetTorLauncherCallback(mate::Arguments* args) { + brave::TorLauncherFactory::TorLauncherCallback callback; + if (!args->GetNext(&callback)) { + args->ThrowError("`callback(result, pid)` is a required field"); + return; + } + brave::BraveBrowserContext* brave_browser_context = + brave::BraveBrowserContext::FromBrowserContext(profile_); + if (!brave_browser_context->IsTorBrowserContext()) { + LOG(ERROR) << __func__ << " only available for tor browser context"; + return; + } + brave_browser_context->SetTorLauncherCallback(callback); +} + // static mate::Handle Session::CreateFrom( v8::Isolate* isolate, content::BrowserContext* browser_context) { @@ -659,6 +729,11 @@ void Session::BuildPrototype(v8::Isolate* isolate, &Session::AllowNTLMCredentialsForDomains) .SetMethod("setEnableBrotli", &Session::SetEnableBrotli) .SetMethod("equal", &Session::Equal) + .SetMethod("isOffTheRecord", &Session::IsOffTheRecord) + .SetMethod("setTorNewIdentity", &Session::SetTorNewIdentity) + .SetMethod("relaunchTor", &Session::RelaunchTor) + .SetMethod("setTorLauncherCallback", &Session::SetTorLauncherCallback) + .SetMethod("getTorPid", &Session::GetTorPid) .SetProperty("partition", &Session::Partition) .SetProperty("contentSettings", &Session::ContentSettings) .SetProperty("userPrefs", &Session::UserPrefs) diff --git a/atom/browser/api/atom_api_session.h b/atom/browser/api/atom_api_session.h index a652ca4877..187e9a6165 100644 --- a/atom/browser/api/atom_api_session.h +++ b/atom/browser/api/atom_api_session.h @@ -93,6 +93,12 @@ class Session: public mate::TrackableObject, v8::Local SpellChecker(v8::Isolate* isolate); v8::Local Extensions(v8::Isolate* isolate); bool Equal(Session* session) const; + bool IsOffTheRecord() const; + void SetTorNewIdentity(const GURL& url, + const base::Closure& callback) const; + void RelaunchTor() const; + void SetTorLauncherCallback(mate::Arguments* args); + int64_t GetTorPid() const; protected: Session(v8::Isolate* isolate, Profile* browser_context); diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index f8e0025bef..edf00725e3 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -413,6 +413,18 @@ mate::Handle SessionFromOptions(v8::Isolate* isolate, if (options.Get("parent_partition", &parent_partition)) { session_options.SetString("parent_partition", parent_partition); } + bool isolated_storage; + if (options.Get("isolated_storage", &isolated_storage)) { + session_options.SetBoolean("isolated_storage", isolated_storage); + } + std::string tor_proxy; + if (options.Get("tor_proxy", &tor_proxy)) { + session_options.SetString("tor_proxy", tor_proxy); + } + std::string tor_path; + if (options.Get("tor_path", &tor_path)) { + session_options.SetString("tor_path", tor_path); + } session = Session::FromPartition(isolate, partition, session_options); } else { // Use the default session if not specified. diff --git a/atom/browser/extensions/atom_extensions_network_delegate.h b/atom/browser/extensions/atom_extensions_network_delegate.h index 3ab0d6114f..e9b10d0952 100644 --- a/atom/browser/extensions/atom_extensions_network_delegate.h +++ b/atom/browser/extensions/atom_extensions_network_delegate.h @@ -30,20 +30,24 @@ class AtomExtensionsNetworkDelegate : public atom::AtomNetworkDelegate { static void SetAcceptAllCookies(bool accept); + protected: + int OnBeforeURLRequest(net::URLRequest* request, + const net::CompletionCallback& callback, + GURL* new_url) override; + int OnBeforeStartTransaction(net::URLRequest* request, + const net::CompletionCallback& callback, + net::HttpRequestHeaders* headers) override; + void OnBeforeRedirect(net::URLRequest* request, + const GURL& new_location) override; + private: // NetworkDelegate implementation. int OnBeforeURLRequestInternal( net::URLRequest* request, GURL* new_url); - int OnBeforeURLRequest(net::URLRequest* request, - const net::CompletionCallback& callback, - GURL* new_url) override; int OnBeforeStartTransactionInternal( net::URLRequest* request, net::HttpRequestHeaders* headers); - int OnBeforeStartTransaction(net::URLRequest* request, - const net::CompletionCallback& callback, - net::HttpRequestHeaders* headers) override; void OnStartTransaction(net::URLRequest* request, const net::HttpRequestHeaders& headers) override; int OnHeadersReceivedInternal( @@ -57,8 +61,6 @@ class AtomExtensionsNetworkDelegate : public atom::AtomNetworkDelegate { const net::HttpResponseHeaders* original_response_headers, scoped_refptr* override_response_headers, GURL* allowed_unsafe_redirect_url) override; - void OnBeforeRedirect(net::URLRequest* request, - const GURL& new_location) override; void OnResponseStarted(net::URLRequest* request, int net_error) override; void OnCompleted(net::URLRequest* request, bool started, diff --git a/atom/utility/atom_content_utility_client.cc b/atom/utility/atom_content_utility_client.cc index b8ed31ea59..2dc999fe5e 100644 --- a/atom/utility/atom_content_utility_client.cc +++ b/atom/utility/atom_content_utility_client.cc @@ -10,7 +10,9 @@ #include "base/files/file_path.h" #include "base/memory/ref_counted.h" #include "base/time/time.h" +#include "brave/common/tor/tor.mojom.h" #include "brave/utility/importer/brave_profile_import_service.h" +#include "brave/utility/tor/tor_service.h" #include "chrome/common/importer/profile_import.mojom.h" #include "components/services/unzip/public/interfaces/constants.mojom.h" #include "components/services/unzip/unzip_service.h" @@ -129,6 +131,12 @@ void AtomContentUtilityClient::RegisterServices( base::BindRepeating(&unzip::UnzipService::CreateService); services->emplace(unzip::mojom::kServiceName, service_info); } + + service_manager::EmbeddedServiceInfo tor_info; + tor_info.factory = + base::Bind(&TorService::CreateService); + services->emplace(tor::mojom::kTorServiceName, + tor_info); } // static diff --git a/brave/browser/BUILD.gn b/brave/browser/BUILD.gn index ead7f6fd62..871e775aa6 100644 --- a/brave/browser/BUILD.gn +++ b/brave/browser/BUILD.gn @@ -45,6 +45,8 @@ source_set("browser") { deps = [ ":apis", + ":proxy", + ":tor", "//electron/atom/browser", "//electron:common", "//electron/muon/app", @@ -156,3 +158,36 @@ source_set("apis") { "component_updater", ] } + +source_set("proxy") { + configs += [ + "//electron/build:electron_config", + ] + + sources = [ + "net/proxy_resolution/proxy_config_service_tor.cc", + "net/proxy_resolution/proxy_config_service_tor.h", + "net/tor_proxy_network_delegate.cc", + "net/tor_proxy_network_delegate.h", + ] + + deps = [ + "//net", + "//third_party/blink/public:blink_headers", + ] +} + +source_set("tor") { + configs += [ + "//electron/build:electron_config", + ] + + sources = [ + "tor/tor_launcher_factory.cc", + "tor/tor_launcher_factory.h", + ] + + deps = [ + "//third_party/blink/public:blink_headers", + ] +} diff --git a/brave/browser/brave_browser_context.cc b/brave/browser/brave_browser_context.cc index b79c3aea23..aa1b0fd0b5 100644 --- a/brave/browser/brave_browser_context.cc +++ b/brave/browser/brave_browser_context.cc @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include +#include #include #include @@ -12,6 +14,7 @@ #include "base/files/file_util.h" #include "base/trace_event/trace_event.h" #include "brave/browser/brave_permission_manager.h" +#include "brave/browser/net/tor_proxy_network_delegate.h" #include "chrome/browser/background_fetch/background_fetch_delegate_factory.h" #include "chrome/browser/background_fetch/background_fetch_delegate_impl.h" #include "chrome/browser/browser_process.h" @@ -44,17 +47,25 @@ #include "components/zoom/zoom_event_manager.h" #include "components/webdata_services/web_data_service_wrapper.h" #include "components/webdata/common/webdata_constants.h" +#include "content/browser/storage_partition_impl_map.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_source.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/dom_storage_context.h" +#include "content/public/browser/site_instance.h" #include "content/public/browser/storage_partition.h" +#include "content/public/common/service_manager_connection.h" +#include "services/service_manager/public/cpp/connector.h" #include "extensions/browser/pref_names.h" #include "extensions/buildflags/buildflags.h" #include "net/base/escape.h" #include "net/cookies/cookie_store.h" +#include "net/proxy_resolution/proxy_resolution_service.h" #include "net/url_request/url_request_context.h" +#include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_job_factory_impl.h" +#include "vendor/brightray/browser/browser_client.h" +#include "vendor/brightray/browser/net_log.h" #if BUILDFLAG(ENABLE_EXTENSIONS) #include "atom/browser/extensions/atom_browser_client_extensions_part.h" @@ -169,6 +180,8 @@ BraveBrowserContext::BraveBrowserContext( ready_(new base::WaitableEvent( base::WaitableEvent::ResetPolicy::MANUAL, base::WaitableEvent::InitialState::NOT_SIGNALED)), + isolated_storage_(false), + in_memory_(in_memory), io_task_runner_(std::move(io_task_runner)), delegate_(g_browser_process->profile_manager()) { std::string parent_partition; @@ -178,6 +191,22 @@ BraveBrowserContext::BraveBrowserContext( atom::AtomBrowserContext::From(parent_partition, false)); } + bool isolated_storage; + if (options.GetBoolean("isolated_storage", &isolated_storage)) { + isolated_storage_ = isolated_storage; + } + + std::string tor_proxy; + if (options.GetString("tor_proxy", &tor_proxy)) { + tor_proxy_ = tor_proxy; + } + + base::FilePath::StringType tor_path; + if (options.GetString("tor_path", &tor_path) && tor_proxy_.length()) { + tor_launcher_factory_.reset(new TorLauncherFactory(tor_path, tor_proxy_)); + tor_launcher_factory_->LaunchTorProcess(); + } + if (in_memory) { original_context_ = static_cast( atom::AtomBrowserContext::From(partition, false)); @@ -317,6 +346,60 @@ content::BrowserPluginGuestManager* BraveBrowserContext::GetGuestManager() { return guest_view::GuestViewManager::FromBrowserContext(this); } +net::URLRequestContextGetter* +BraveBrowserContext::CreateRequestContextForStoragePartition( + const base::FilePath& partition_path, + bool in_memory, + content::ProtocolHandlerMap* protocol_handlers, + content::URLRequestInterceptorScopedVector request_interceptors) { + if (isolated_storage_) { + scoped_refptr + url_request_context_getter = + new brightray::URLRequestContextGetter( + this, + static_cast(brightray::BrowserClient::Get()-> + GetNetLog()), + partition_path, + in_memory, + BrowserThread::GetTaskRunnerForThread(BrowserThread::IO), + protocol_handlers, + std::move(request_interceptors)); + StoragePartitionDescriptor descriptor(partition_path, in_memory); + // Inherits web requests handlers from default parition + auto default_network_delegate = GetDefaultStoragePartition(this)-> + GetURLRequestContext()->GetURLRequestContext()->network_delegate(); + url_request_context_getter->GetURLRequestContext() + ->set_network_delegate(default_network_delegate); + url_request_context_getter_map_[descriptor] = url_request_context_getter; + return url_request_context_getter.get(); + } else { + return nullptr; + } +} + +net::URLRequestContextGetter* +BraveBrowserContext::CreateMediaRequestContextForStoragePartition( + const base::FilePath& partition_path, + bool in_memory) { + if (isolated_storage_) { + StoragePartitionDescriptor descriptor(partition_path, in_memory); + URLRequestContextGetterMap::iterator iter = + url_request_context_getter_map_.find(descriptor); + if (iter != url_request_context_getter_map_.end()) + return (iter->second).get(); + else + return nullptr; + } else { + return nullptr; + } +} + +bool BraveBrowserContext::IsOffTheRecord() const { + if (isolated_storage_) + return true; + return in_memory_; +} + void BraveBrowserContext::TrackZoomLevelsFromParent() { // Here we only want to use zoom levels stored in the main-context's default // storage partition. We're not interested in zoom levels in special @@ -392,9 +475,14 @@ net::URLRequestContextGetter* BraveBrowserContext::GetRequestContext() { net::NetworkDelegate* BraveBrowserContext::CreateNetworkDelegate() { DCHECK_CURRENTLY_ON(BrowserThread::IO); - return new extensions::AtomExtensionsNetworkDelegate(this, - info_map_, - g_browser_process->extension_event_router_forwarder()); + if (isolated_storage_) + return new brave::TorProxyNetworkDelegate(this, + info_map_, + g_browser_process->extension_event_router_forwarder()); + else + return new extensions::AtomExtensionsNetworkDelegate(this, + info_map_, + g_browser_process->extension_event_router_forwarder()); } std::unique_ptr @@ -414,6 +502,11 @@ BraveBrowserContext::CreateURLRequestJobFactory( extensions::CreateExtensionProtocolHandler(IsOffTheRecord(), info_map_)); #endif + if (!protocol_handler_interceptor_.get()) { + protocol_handler_interceptor_ = + ProtocolHandlerRegistryFactory::GetForBrowserContext(this) + ->CreateJobInterceptorFactory(); + } protocol_handler_interceptor_->Chain(std::move(job_factory)); return std::move(protocol_handler_interceptor_); } @@ -596,7 +689,7 @@ std::string BraveBrowserContext::partition_with_prefix() { if (canonical_partition.empty()) canonical_partition = "default"; - if (IsOffTheRecord()) + if (IsOffTheRecord() && !isolated_storage_) return canonical_partition; return kPersistPrefix + canonical_partition; @@ -634,6 +727,52 @@ void BraveBrowserContext::SetExitType(ExitType exit_type) { } } +void BraveBrowserContext::SetTorNewIdentity(const GURL& url, + const base::Closure& callback) { + GURL site_url(content::SiteInstance::GetSiteForURL(this, url)); + const std::string host = site_url.host(); + base::FilePath partition_path = this->GetPath().Append( + content::StoragePartitionImplMap::GetStoragePartitionPath(host, host)); + scoped_refptr url_request_context_getter; + StoragePartitionDescriptor descriptor(partition_path, true); + URLRequestContextGetterMap::iterator iter = + url_request_context_getter_map_.find(descriptor); + if (iter != url_request_context_getter_map_.end()) + url_request_context_getter = (iter->second); + else + return; + auto proxy_resolution_service = + url_request_context_getter->GetURLRequestContext()-> + proxy_resolution_service(); + BrowserThread::PostTaskAndReply( + BrowserThread::IO, FROM_HERE, + base::Bind(&net::ProxyConfigServiceTor::TorSetProxy, + proxy_resolution_service, + tor_proxy_, + host, + &tor_proxy_map_, + true), + callback); +} + +void BraveBrowserContext::RelaunchTor() const { + if (tor_launcher_factory_.get()) + tor_launcher_factory_->RelaunchTorProcess(); +} + +void BraveBrowserContext::SetTorLauncherCallback( + const TorLauncherFactory::TorLauncherCallback& callback) { + if (tor_launcher_factory_.get()) + tor_launcher_factory_->SetLauncherCallback(callback); +} + +int64_t BraveBrowserContext::GetTorPid() const { + if (tor_launcher_factory_.get()) + return tor_launcher_factory_->GetTorPid(); + else + return -1; +} + scoped_refptr BraveBrowserContext::GetIOTaskRunner() { return io_task_runner_; diff --git a/brave/browser/brave_browser_context.h b/brave/browser/brave_browser_context.h index cfcb8d5751..1cecd17c91 100644 --- a/brave/browser/brave_browser_context.h +++ b/brave/browser/brave_browser_context.h @@ -5,13 +5,17 @@ #ifndef BRAVE_BROWSER_BRAVE_BROWSER_CONTEXT_H_ #define BRAVE_BROWSER_BRAVE_BROWSER_CONTEXT_H_ +#include #include #include #include #include "atom/browser/atom_browser_context.h" +#include "brave/browser/tor/tor_launcher_factory.h" +#include "brave/browser/net/proxy_resolution/proxy_config_service_tor.h" #include "content/public/browser/host_zoom_map.h" #include "chrome/browser/custom_handlers/protocol_handler_registry.h" +#include "chrome/browser/profiles/storage_partition_descriptor.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h" #include "components/prefs/overlay_user_pref_store.h" @@ -78,6 +82,15 @@ class BraveBrowserContext : public Profile { override { return nullptr; } + net::URLRequestContextGetter* CreateRequestContextForStoragePartition( + const base::FilePath& partition_path, + bool in_memory, + content::ProtocolHandlerMap* protocol_handlers, + content::URLRequestInterceptorScopedVector request_interceptors) override; + net::URLRequestContextGetter* CreateMediaRequestContextForStoragePartition( + const base::FilePath& partition_path, + bool in_memory) override; + bool IsOffTheRecord() const override; // Profile implementation: scoped_refptr GetIOTaskRunner() override; @@ -130,7 +143,31 @@ class BraveBrowserContext : public Profile { void SetExitType(ExitType exit_type) override; + bool IsIsolatedStorage() const { return isolated_storage_; } + + bool IsTorBrowserContext() const { + return tor_launcher_factory_.get(); + } + + void SetTorNewIdentity(const GURL& url, const base::Closure& callback); + + const std::string& tor_proxy() { return tor_proxy_; } + + net::ProxyConfigServiceTor::TorProxyMap* tor_proxy_map() { + return &tor_proxy_map_; } + + void RelaunchTor() const; + + void SetTorLauncherCallback( + const TorLauncherFactory::TorLauncherCallback& callback); + + int64_t GetTorPid() const; + private: + typedef std::map, + StoragePartitionDescriptorLess> + URLRequestContextGetterMap; void OnPrefsLoaded(bool success); void TrackZoomLevelsFromParent(); void OnParentZoomLevelChanged( @@ -153,10 +190,18 @@ class BraveBrowserContext : public Profile { BraveBrowserContext* otr_context_; const std::string partition_; std::unique_ptr ready_; + bool isolated_storage_; + bool in_memory_; + std::string tor_proxy_; + + net::ProxyConfigServiceTor::TorProxyMap tor_proxy_map_; + + URLRequestContextGetterMap url_request_context_getter_map_; std::unique_ptr web_database_wrapper_; std::unique_ptr protocol_handler_interceptor_; + std::unique_ptr tor_launcher_factory_; // Task runner used for file access in the profile path scoped_refptr io_task_runner_; diff --git a/brave/browser/brave_content_browser_client.cc b/brave/browser/brave_content_browser_client.cc index 447fe4c74f..982c1b97d1 100644 --- a/brave/browser/brave_content_browser_client.cc +++ b/brave/browser/brave_content_browser_client.cc @@ -17,10 +17,13 @@ #include "base/lazy_instance.h" #include "base/path_service.h" #include "base/strings/utf_string_conversions.h" +#include "brave/browser/brave_browser_context.h" #include "brave/browser/notifications/platform_notification_service_impl.h" #include "brave/browser/password_manager/brave_password_manager_client.h" #include "brave/browser/renderer_host/brave_render_message_filter.h" +#include "brave/common/tor/tor.mojom.h" #include "brave/grit/brave_resources.h" +#include "brave/grit/brave_strings.h" // NOLINT: This file is generated #include "chrome/browser/browser_process.h" #include "chrome/browser/cache_stats_recorder.h" #include "chrome/browser/chrome_service.h" @@ -278,6 +281,12 @@ std::string BraveContentBrowserClient::GetStoragePartitionIdForSite( partition_id = site.spec(); #endif + auto brave_browser_context = + BraveBrowserContext::FromBrowserContext(browser_context); + if (brave_browser_context && brave_browser_context->IsIsolatedStorage()) { + partition_id = site.spec(); + } + DCHECK(IsValidStoragePartitionId(browser_context, partition_id)); return partition_id; } @@ -347,6 +356,17 @@ void BraveContentBrowserClient::GetStoragePartitionConfigForSite( // error about which StoragePartition they expect to be in and it is not // safe to continue. CHECK(can_be_default || !partition_domain->empty()); + + auto brave_browser_context = + BraveBrowserContext::FromBrowserContext(browser_context); + if (brave_browser_context && brave_browser_context->IsIsolatedStorage() && + !site.SchemeIs(extensions::kExtensionScheme)) { + if (!site.is_empty()) { + *partition_domain = site.host(); + *partition_name = site.host(); + } + *in_memory = brave_browser_context->IsOffTheRecord(); + } } content::WebContentsViewDelegate* @@ -400,11 +420,14 @@ void BraveContentBrowserClient::RegisterOutOfProcessServices( l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_PROXY_RESOLVER_NAME); #if BUILDFLAG(ENABLE_PRINT_PREVIEW) - (*services)[printing::mojom::kChromePrintingServiceName] = + (*services)[printing::mojom::kChromePrintingServiceName] = l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_PRINTING_SERVICE_NAME); #endif - (*services)[unzip::mojom::kServiceName] = + (*services)[unzip::mojom::kServiceName] = l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_UNZIP_NAME); + + (*services)[tor::mojom::kTorServiceName] = + l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_TOR_LAUNCHER_NAME); } void BraveContentBrowserClient::BindInterfaceRequest( @@ -756,6 +779,11 @@ void BraveContentBrowserClient::SiteInstanceDeleting( bool BraveContentBrowserClient::ShouldUseProcessPerSite( content::BrowserContext* browser_context, const GURL& effective_url) { + auto brave_browser_context = + BraveBrowserContext::FromBrowserContext(browser_context); + if (brave_browser_context && brave_browser_context->IsIsolatedStorage()) + return true; + Profile* profile = Profile::FromBrowserContext(browser_context); if (!profile) return false; diff --git a/brave/browser/guest_view/tab_view/tab_view_guest.cc b/brave/browser/guest_view/tab_view/tab_view_guest.cc index 7f76cdcadb..9b3ba4808a 100644 --- a/brave/browser/guest_view/tab_view/tab_view_guest.cc +++ b/brave/browser/guest_view/tab_view/tab_view_guest.cc @@ -297,6 +297,10 @@ void TabViewGuest::CreateWebContents( partition_options.SetString("parent_partition", ""); } } + bool isolated_storage; + if (params.GetBoolean("isolated_storage", &isolated_storage)) { + partition_options.SetBoolean("isolated_storage", isolated_storage); + } atom::AtomBrowserContext* browser_context = brave::BraveBrowserContext::FromPartition(partition, partition_options); diff --git a/brave/browser/net/proxy_resolution/proxy_config_service_tor.cc b/brave/browser/net/proxy_resolution/proxy_config_service_tor.cc new file mode 100644 index 0000000000..5f1eccb26b --- /dev/null +++ b/brave/browser/net/proxy_resolution/proxy_config_service_tor.cc @@ -0,0 +1,167 @@ +// Copyright (c) 2018 The Brave Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "brave/browser/net/proxy_resolution/proxy_config_service_tor.h" + +#include +#include +#include +#include +#include + +#include "base/time/time.h" +#include "base/values.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" +#include "content/public/browser/browser_thread.h" +#include "crypto/random.h" +#include "net/proxy_resolution/proxy_resolution_service.h" +#include "net/url_request/url_request_context.h" +#include "vendor/brightray/browser/browser_client.h" +#include "vendor/brightray/browser/net_log.h" +#include "url/third_party/mozilla/url_parse.h" + +namespace net { + +using content::BrowserThread; +const int kTorPasswordLength = 16; +// Default tor circuit life time is 10 minutes +constexpr base::TimeDelta kTenMins = base::TimeDelta::FromMinutes(10); + +ProxyConfigServiceTor::ProxyConfigServiceTor( + const std::string& tor_proxy, const std::string& username, + TorProxyMap* tor_proxy_map) { + if (tor_proxy.length()) { + url::Parsed url; + url::ParseStandardURL( + tor_proxy.c_str(), + std::min(tor_proxy.size(), + static_cast(std::numeric_limits::max())), + &url); + if (url.scheme.is_valid()) { + scheme_ = + std::string(tor_proxy.begin() + url.scheme.begin, + tor_proxy.begin() + url.scheme.begin + url.scheme.len); + } + if (url.host.is_valid()) { + host_ = + std::string(tor_proxy.begin() + url.host.begin, + tor_proxy.begin() + url.host.begin + url.host.len); + } + if (url.port.is_valid()) { + port_ = + std::string(tor_proxy.begin() + url.port.begin, + tor_proxy.begin() + url.port.begin + url.port.len); + } + std::string proxy_url; + if (tor_proxy_map && !username.empty()) { + std::string password = tor_proxy_map->Get(username); + proxy_url = std::string(scheme_ + "://" + username + ":" + password + + "@" + host_ + ":" + port_); + } else { + proxy_url = std::string(scheme_ + "://" + host_ + ":" + port_); + } + config_.proxy_rules().ParseFromString(proxy_url); + } +} + +ProxyConfigServiceTor::~ProxyConfigServiceTor() {} + +void ProxyConfigServiceTor::TorSetProxy( + net::ProxyResolutionService* service, + const std::string& tor_proxy, + const std::string& site_url, + TorProxyMap* tor_proxy_map, + bool new_password) { + if (!service) + return; + if (new_password && tor_proxy_map) + tor_proxy_map->Erase(site_url); + std::unique_ptr + config(new ProxyConfigServiceTor(tor_proxy, site_url, tor_proxy_map)); + service->ResetConfigService(std::move(config)); +} + +ProxyConfigServiceTor::ConfigAvailability + ProxyConfigServiceTor::GetLatestProxyConfig( + ProxyConfigWithAnnotation* config) { + if (scheme_ != kSocksProxy || host_.empty() || port_.empty()) + return CONFIG_UNSET; + *config = net:: ProxyConfigWithAnnotation(config_, NO_TRAFFIC_ANNOTATION_YET); + return CONFIG_VALID; +} + +ProxyConfigServiceTor::TorProxyMap::TorProxyMap() = default; +ProxyConfigServiceTor::TorProxyMap::~TorProxyMap() = default; + +// static +std::string ProxyConfigServiceTor::TorProxyMap::GenerateNewPassword() { + std::vector password(kTorPasswordLength); + crypto::RandBytes(password.data(), password.size()); + return base::HexEncode(password.data(), password.size()); +} + +std::string ProxyConfigServiceTor::TorProxyMap::Get( + const std::string& username) { + // Clear any expired entries, in case this one has expired. + ClearExpiredEntries(); + + // Check for an entry for this username. + auto found = map_.find(username); + if (found != map_.end()) + return found->second.first; + + // No entry yet. Check our watch and create one. + const base::Time now = base::Time::Now(); + const std::string password = GenerateNewPassword(); + map_.emplace(username, std::make_pair(password, now)); + queue_.emplace(now, username); + + // Reschedule the timer for ten minutes from now so that this entry + // won't last more than about ten minutes even if the user stops + // using Tor for a while. + timer_.Stop(); + timer_.Start(FROM_HERE, kTenMins, this, + &ProxyConfigServiceTor::TorProxyMap::ClearExpiredEntries); + + return password; +} + +void ProxyConfigServiceTor::TorProxyMap::Erase(const std::string& username) { + // Just erase it from the map. There will remain an entry in the + // queue, but it is harmless. If anyone creates a new entry in the + // map, the old entry in the queue will cease to affect it because + // the timestamps won't match, and they will simultaneously create a + // new entry in the queue. + map_.erase(username); +} + +void ProxyConfigServiceTor::TorProxyMap::ClearExpiredEntries() { + const base::Time cutoff = base::Time::Now() - kTenMins; + for (; !queue_.empty(); queue_.pop()) { + // Check the timestamp. If it's not older than the cutoff, stop. + const std::pair* entry = &queue_.top(); + const base::Time timestamp = entry->first; + if (!(timestamp < cutoff)) + break; + + // Remove the corresponding entry in the map if there is one and + // if its timestamp is not newer. + const std::string& username = entry->second; + auto found = map_.find(username); + if (found != map_.end()) { + // If the timestamp on the map entry is the same as the + // timestamp on the queue entry, then delete the map entry. + // Otherwise, we assume the map entry was created by an explicit + // request for a new identity, which will have its own entry in + // the queue in order to last the full ten minutes. + const base::Time map_timestamp = found->second.second; + if (map_timestamp == timestamp) { + map_.erase(username); + } + } + } +} + +} // namespace net diff --git a/brave/browser/net/proxy_resolution/proxy_config_service_tor.h b/brave/browser/net/proxy_resolution/proxy_config_service_tor.h new file mode 100644 index 0000000000..53d40bc12b --- /dev/null +++ b/brave/browser/net/proxy_resolution/proxy_config_service_tor.h @@ -0,0 +1,78 @@ +// Copyright (c) 2018 The Brave Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BRAVE_BROWSER_NET_PROXY_RESOLUTION_PROXY_CONFIG_SERVICE_TOR_H_ +#define BRAVE_BROWSER_NET_PROXY_RESOLUTION_PROXY_CONFIG_SERVICE_TOR_H_ + +#include +#include +#include +#include + +#include "base/compiler_specific.h" +#include "base/timer/timer.h" +#include "net/base/net_errors.h" +#include "net/base/net_export.h" +#include "net/proxy_resolution/proxy_config.h" +#include "net/proxy_resolution/proxy_config_service.h" +#include "vendor/brightray/browser/url_request_context_getter.h" + +namespace base { +class Time; +} + +namespace net { + +const char kSocksProxy[] = "socks5"; + +// Implementation of ProxyConfigService that returns a tor specific result. +class NET_EXPORT ProxyConfigServiceTor : public ProxyConfigService { + public: + // Used to cache of proxies + class TorProxyMap { + public: + TorProxyMap(); + ~TorProxyMap(); + std::string Get(const std::string&); + void Erase(const std::string&); + private: + // Generate a new 128 bit random tag + static std::string GenerateNewPassword(); + // Clear expired entries in the queue from the map. + void ClearExpiredEntries(); + std::map > map_; + std::priority_queue > queue_; + base::OneShotTimer timer_; + DISALLOW_COPY_AND_ASSIGN(TorProxyMap); + }; + + explicit ProxyConfigServiceTor(const std::string& tor_proxy, + const std::string& username, + TorProxyMap* map); + ~ProxyConfigServiceTor() override; + + static void TorSetProxy( + net::ProxyResolutionService* service, + const std::string& tor_proxy, + const std::string& site_url, + TorProxyMap* tor_proxy_map, + bool new_password); + + // ProxyConfigService methods: + void AddObserver(Observer* observer) override {} + void RemoveObserver(Observer* observer) override {} + ConfigAvailability GetLatestProxyConfig( + ProxyConfigWithAnnotation* config) override; + + private: + ProxyConfig config_; + + std::string scheme_; + std::string host_; + std::string port_; +}; + +} // namespace net + +#endif // BRAVE_BROWSER_NET_PROXY_RESOLUTION_PROXY_CONFIG_SERVICE_TOR_H_ diff --git a/brave/browser/net/tor_proxy_network_delegate.cc b/brave/browser/net/tor_proxy_network_delegate.cc new file mode 100644 index 0000000000..8336ddd3fe --- /dev/null +++ b/brave/browser/net/tor_proxy_network_delegate.cc @@ -0,0 +1,75 @@ +// Copyright 2018 The Brave Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "brave/browser/net/tor_proxy_network_delegate.h" + +#include "brave/browser/net/proxy_resolution/proxy_config_service_tor.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/site_instance.h" +#include "extensions/common/constants.h" +#include "net/base/url_util.h" +#include "net/url_request/url_request.h" +#include "net/url_request/url_request_context.h" + +using content::BrowserThread; + +namespace brave { + +TorProxyNetworkDelegate::TorProxyNetworkDelegate( + Profile* profile, + extensions::InfoMap* info_map, + extensions::EventRouterForwarder* event_router) : + extensions::AtomExtensionsNetworkDelegate(profile, info_map, + event_router), + browser_context_(static_cast(profile)) {} + +TorProxyNetworkDelegate::~TorProxyNetworkDelegate() {} + +int TorProxyNetworkDelegate::OnBeforeURLRequest( + net::URLRequest* request, + const net::CompletionCallback& callback, + GURL* new_url) { + ConfigTorProxyInteral(request); + return extensions::AtomExtensionsNetworkDelegate::OnBeforeURLRequest(request, + callback, + new_url); +} + +int TorProxyNetworkDelegate::OnBeforeStartTransaction( + net::URLRequest* request, + const net::CompletionCallback& callback, + net::HttpRequestHeaders* headers) { + ConfigTorProxyInteral(request); + return extensions::AtomExtensionsNetworkDelegate:: + OnBeforeStartTransaction(request, + callback, + headers); +} + +void TorProxyNetworkDelegate::OnBeforeRedirect( + net::URLRequest* request, + const GURL& new_location) { + ConfigTorProxyInteral(request); + extensions::AtomExtensionsNetworkDelegate::OnBeforeRedirect(request, + new_location); +} + +void TorProxyNetworkDelegate::ConfigTorProxyInteral(net::URLRequest* request) { + if (!request) + return; + auto proxy_service = request->context()->proxy_resolution_service(); + GURL url(content::SiteInstance::GetSiteForURL(browser_context_, + request->url())); + if (!url.SchemeIs(extensions::kExtensionScheme) && !net::IsLocalhost(url) && + !url.host().empty()) + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::Bind(&net::ProxyConfigServiceTor::TorSetProxy, + proxy_service, + browser_context_->tor_proxy(), + url.host(), + browser_context_->tor_proxy_map(), + false)); +} + +} // namespace brave diff --git a/brave/browser/net/tor_proxy_network_delegate.h b/brave/browser/net/tor_proxy_network_delegate.h new file mode 100644 index 0000000000..66413a3c06 --- /dev/null +++ b/brave/browser/net/tor_proxy_network_delegate.h @@ -0,0 +1,47 @@ +// Copyright 2018 The Brave Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BRAVE_BROWSER_NET_TOR_PROXY_NETWORK_DELEGATE_H_ +#define BRAVE_BROWSER_NET_TOR_PROXY_NETWORK_DELEGATE_H_ + +#include "atom/browser/extensions/atom_extensions_network_delegate.h" +#include "brave/browser/brave_browser_context.h" + +namespace extensions { +class EventRouterForwarder; +class InfoMap; +} + +namespace brave { + +class TorProxyNetworkDelegate : + public extensions::AtomExtensionsNetworkDelegate { + public: + explicit TorProxyNetworkDelegate( + Profile* browser_context, + extensions::InfoMap* info_map, + extensions::EventRouterForwarder* event_router); + ~TorProxyNetworkDelegate() override; + + private: + // NetworkDelegate implementation. + int OnBeforeURLRequest(net::URLRequest* request, + const net::CompletionCallback& callback, + GURL* new_url) override; + int OnBeforeStartTransaction(net::URLRequest* request, + const net::CompletionCallback& callback, + net::HttpRequestHeaders* headers) override; + void OnBeforeRedirect(net::URLRequest* request, + const GURL& new_location) override; + + void ConfigTorProxyInteral(net::URLRequest* request); + + BraveBrowserContext* browser_context_; + + DISALLOW_COPY_AND_ASSIGN(TorProxyNetworkDelegate); +}; + +} // namespace brave + +#endif // BRAVE_BROWSER_NET_TOR_PROXY_NETWORK_DELEGATE_H_ diff --git a/brave/browser/tor/tor_launcher_factory.cc b/brave/browser/tor/tor_launcher_factory.cc new file mode 100644 index 0000000000..90f3479126 --- /dev/null +++ b/brave/browser/tor/tor_launcher_factory.cc @@ -0,0 +1,123 @@ +// Copyright 2018 The Brave Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "brave/browser/tor/tor_launcher_factory.h" + +#include +#include + +#include "base/files/file_util.h" +#include "base/path_service.h" +#include "chrome/common/chrome_paths.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/child_process_launcher_utils.h" +#include "content/public/common/service_manager_connection.h" +#include "services/service_manager/public/cpp/connector.h" +#include "url/third_party/mozilla/url_parse.h" + +namespace brave { + +using content::BrowserThread; + +TorLauncherFactory::TorLauncherFactory( + const base::FilePath::StringType& path, const std::string& proxy) + : path_(path) { + if (proxy.length()) { + url::Parsed url; + url::ParseStandardURL( + proxy.c_str(), + std::min(proxy.size(), + static_cast(std::numeric_limits::max())), + &url); + if (url.host.is_valid()) { + host_ = + std::string(proxy.begin() + url.host.begin, + proxy.begin() + url.host.begin + url.host.len); + } + if (url.port.is_valid()) { + port_ = + std::string(proxy.begin() + url.port.begin, + proxy.begin() + url.port.begin + url.port.len); + } + } + + content::ServiceManagerConnection::GetForProcess()->GetConnector() + ->BindInterface(tor::mojom::kTorServiceName, + &tor_launcher_); + + tor_launcher_.set_connection_error_handler( + base::BindOnce(&TorLauncherFactory::OnTorLauncherCrashed, + base::Unretained(this))); +} + +TorLauncherFactory::~TorLauncherFactory() {} + +void TorLauncherFactory::LaunchTorProcess() { + content::GetProcessLauncherTaskRunner()->PostTask( + FROM_HERE, base::Bind(&TorLauncherFactory::LaunchOnLauncherThread, + base::Unretained(this))); +} + +void TorLauncherFactory::RelaunchTorProcess() { + content::GetProcessLauncherTaskRunner()->PostTask( + FROM_HERE, base::Bind(&TorLauncherFactory::RelaunchOnLauncherThread, + base::Unretained(this))); +} + +void TorLauncherFactory::SetLauncherCallback( + const TorLauncherCallback& callback) { + callback_ = callback; +} + +void TorLauncherFactory::LaunchOnLauncherThread() { + base::FilePath user_data_dir; + PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); + if (!user_data_dir.empty()) { + tor_data_path_ = user_data_dir.Append(FILE_PATH_LITERAL("tor")) + .Append(FILE_PATH_LITERAL("data")); + base::CreateDirectory(tor_data_path_); + tor_watch_path_ = user_data_dir.Append(FILE_PATH_LITERAL("tor")) + .Append(FILE_PATH_LITERAL("watch")); + base::CreateDirectory(tor_watch_path_); + } + tor_launcher_->Launch(base::FilePath(path_), host_, port_, tor_data_path_, + tor_watch_path_, + base::Bind(&TorLauncherFactory::OnTorLaunched, + base::Unretained(this))); + tor_launcher_->SetCrashHandler(base::Bind( + &TorLauncherFactory::OnTorCrashed, + base::Unretained(this))); +} + +void TorLauncherFactory::RelaunchOnLauncherThread() { + tor_launcher_->Relaunch(base::FilePath(path_), host_, port_, tor_data_path_, + tor_watch_path_, + base::Bind(&TorLauncherFactory::OnTorLaunched, + base::Unretained(this))); +} + +void TorLauncherFactory::OnTorLauncherCrashed() { + LOG(ERROR) << "Tor Launcher Crashed"; +} + +void TorLauncherFactory::OnTorCrashed(int64_t pid) { + LOG(ERROR) << "Tor Process(" << pid << ") Crashed"; + if (callback_) + callback_.Run(TorProcessState::CRASHED, pid); +} + +void TorLauncherFactory::OnTorLaunched(bool result, int64_t pid) { + tor_pid_ = pid; + if (!result) { + LOG(ERROR) << "Tor Launching Failed(" << pid <<")"; + } + if (callback_) { + if (result) + callback_.Run(TorProcessState::LAUNCH_SUCCEEDED, pid); + else + callback_.Run(TorProcessState::LAUNCH_FAILED, pid); + } +} + +} // namespace brave diff --git a/brave/browser/tor/tor_launcher_factory.h b/brave/browser/tor/tor_launcher_factory.h new file mode 100644 index 0000000000..9464f8e653 --- /dev/null +++ b/brave/browser/tor/tor_launcher_factory.h @@ -0,0 +1,58 @@ +// Copyright 2018 The Brave Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BRAVE_BROWSER_TOR_TOR_LAUNCHER_FACTORY_H_ +#define BRAVE_BROWSER_TOR_TOR_LAUNCHER_FACTORY_H_ + +#include + +#include "base/callback.h" +#include "brave/common/tor/tor.mojom.h" + +namespace brave { + +class TorLauncherFactory { + public: + TorLauncherFactory(const base::FilePath::StringType& path, + const std::string& proxy); + ~TorLauncherFactory(); + + enum class TorProcessState { + LAUNCH_SUCCEEDED, + LAUNCH_FAILED, + CRASHED + }; + + using TorLauncherCallback = base::Callback; + + void LaunchTorProcess(); + void RelaunchTorProcess(); + void SetLauncherCallback(const TorLauncherCallback& callback); + int64_t GetTorPid() const { return tor_pid_; } + + private: + void LaunchOnLauncherThread(); + void RelaunchOnLauncherThread(); + + void OnTorLauncherCrashed(); + void OnTorCrashed(int64_t pid); + void OnTorLaunched(bool result, int64_t pid); + + + + tor::mojom::TorLauncherPtr tor_launcher_; + + TorLauncherCallback callback_; + int64_t tor_pid_; + + base::FilePath::StringType path_; + std::string host_; + std::string port_; + base::FilePath tor_data_path_; + base::FilePath tor_watch_path_; +}; + +} // namespace brave + +#endif // BRAVE_BROWSER_TOR_TOR_LAUNCHER_FACTORY_H_ diff --git a/brave/common/tor/tor.mojom b/brave/common/tor/tor.mojom new file mode 100644 index 0000000000..8264cda583 --- /dev/null +++ b/brave/common/tor/tor.mojom @@ -0,0 +1,24 @@ +// Copyright 2018 The Brave Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module tor.mojom; + +import "mojo/public/mojom/base/file_path.mojom"; + +const string kTorServiceName = "tor_launcher"; + +interface TorLauncher { + Launch(mojo_base.mojom.FilePath tor_bin, string tor_host, string tor_port, + mojo_base.mojom.FilePath tor_data_dir, + mojo_base.mojom.FilePath tor_watch_dir) + => (bool result, int64 pid); + + // TODO(darkdh): info of callback can be more granular + SetCrashHandler() => (int64 pid); + + Relaunch(mojo_base.mojom.FilePath tor_bin, string tor_host, string tor_port, + mojo_base.mojom.FilePath tor_data_dir, + mojo_base.mojom.FilePath tor_watch_dir) + => (bool result, int64 pid); +}; diff --git a/brave/utility/tor/tor_launcher_impl.cc b/brave/utility/tor/tor_launcher_impl.cc new file mode 100644 index 0000000000..1f40fdccef --- /dev/null +++ b/brave/utility/tor/tor_launcher_impl.cc @@ -0,0 +1,242 @@ +// Copyright (c) 2018 The Brave Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "brave/utility/tor/tor_launcher_impl.h" + + +#if defined(OS_LINUX) +#include +#include +#include +#include +#include +#endif + +#include + +#include "base/command_line.h" +#include "base/process/kill.h" +#include "base/process/launch.h" +#include "base/single_thread_task_runner.h" +#include "base/task_scheduler/post_task.h" +#include "base/threading/thread.h" +#include "base/threading/thread_task_runner_handle.h" + +#if defined(OS_POSIX) +int pipehack[2]; + +static void SIGCHLDHandler(int signo) { + int error = errno; + char ch = 0; + (void)write(pipehack[1], &ch, 1); + errno = error; +} + +static void SetupPipeHack() { + if (pipe(pipehack) == -1) + LOG(ERROR) << "pipehack"; + + int flags; + for (size_t i = 0; i < 2; ++i) { + if ((flags = fcntl(pipehack[i], F_GETFL)) == -1) + LOG(ERROR) << "get flags"; + // Nonblock write end on SIGCHLD handler which will notify monitor thread + // by sending one byte to pipe whose read end is blocked and wait for + // SIGCHLD to arrives to avoid busy reading + if (i == 1) + flags |= O_NONBLOCK; + if (fcntl(pipehack[i], F_SETFL, flags) == -1) + LOG(ERROR) << "set flags"; + if ((flags = fcntl(pipehack[i], F_GETFD)) == -1) + LOG(ERROR) << "get fd flags"; + flags |= FD_CLOEXEC; + if (fcntl(pipehack[i], F_SETFD, flags) == -1) + LOG(ERROR) << "set fd flags"; + } + + struct sigaction action; + memset(&action, 0, sizeof(action)); + action.sa_handler = SIGCHLDHandler; + sigaction(SIGCHLD, &action, NULL); +} + +static void TearDownPipeHack() { + struct sigaction action; + memset(&action, 0, sizeof(action)); + action.sa_handler = SIG_DFL; + sigaction(SIGCHLD, &action, NULL); + for (size_t i = 0; i < 2; ++i) + close(pipehack[i]); +} +#endif + +namespace brave { + +#if defined(OS_POSIX) +class TorLauncherDelegate : public base::LaunchOptions::PreExecDelegate { + public: + TorLauncherDelegate() {} + ~TorLauncherDelegate() override {} + + void RunAsyncSafe() override { + // Makes tor process a new leader of process group so that it won't get + // affected by ctrl+c (SIGINT) in current terminal + setsid(); + } + private: + DISALLOW_COPY_AND_ASSIGN(TorLauncherDelegate); +}; +#endif + +TorLauncherImpl::TorLauncherImpl( + std::unique_ptr service_ref) + : service_ref_(std::move(service_ref)) { +#if defined(OS_POSIX) + SetupPipeHack(); +#endif +} + +TorLauncherImpl::~TorLauncherImpl() { + if (tor_process_.IsValid()) { + tor_process_.Terminate(0, true); +#if defined(OS_POSIX) + TearDownPipeHack(); +#endif +#if defined(OS_MACOSX) + base::PostTaskWithTraits( + FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND}, + base::BindOnce(&base::EnsureProcessTerminated, Passed(&tor_process_))); +#else + base::EnsureProcessTerminated(std::move(tor_process_)); +#endif + } +} + +void TorLauncherImpl::Launch(const base::FilePath& tor_bin, + const std::string& tor_host, + const std::string& tor_port, + const base::FilePath& tor_data_dir, + const base::FilePath& tor_watch_dir, + LaunchCallback callback) { + base::CommandLine args(tor_bin); + args.AppendArg("--ignore-missing-torrc"); + args.AppendArg("-f"); + args.AppendArg("/nonexistent"); + args.AppendArg("--defaults-torrc"); + args.AppendArg("/nonexistent"); + args.AppendArg("--SocksPort"); + args.AppendArg(tor_host + ":" + tor_port); + args.AppendArg("--TruncateLogFile"); + args.AppendArg("1"); + if (!tor_data_dir.empty()) { + args.AppendArg("--DataDirectory"); + args.AppendArgPath(tor_data_dir); + args.AppendArg("--Log"); + base::CommandLine::StringType log_file; + log_file += FILE_PATH_LITERAL("notice file "); + args.AppendArgNative(log_file + + tor_data_dir.AppendASCII("tor.log").value()); + } + if (!tor_watch_dir.empty()) { + args.AppendArg("--pidfile"); + args.AppendArgPath(tor_watch_dir.AppendASCII("tor.pid")); + args.AppendArg("--controlport"); + args.AppendArg("auto"); + args.AppendArg("--controlportwritetofile"); + args.AppendArgPath(tor_watch_dir.AppendASCII("controlport")); + args.AppendArg("--cookieauthentication"); + args.AppendArg("1"); + args.AppendArg("--cookieauthfile"); + args.AppendArgPath(tor_watch_dir.AppendASCII("control_auth_cookie")); + } + + base::LaunchOptions launchopts; +#if defined(OS_POSIX) + TorLauncherDelegate tor_launcher_delegate; + launchopts.pre_exec_delegate = &tor_launcher_delegate; +#endif +#if defined(OS_LINUX) + launchopts.kill_on_parent_death = true; +#endif +#if defined(OS_WIN) + launchopts.start_hidden = true; +#endif + tor_process_ = base::LaunchProcess(args, launchopts); + + bool result; + // TODO(darkdh): return success when tor connected to tor network + if (tor_process_.IsValid()) + result = true; + else + result = false; + + if (callback) + std::move(callback).Run(result, tor_process_.Pid()); + + if (!child_monitor_thread_.get()) { + child_monitor_thread_.reset(new base::Thread("child_monitor_thread")); + if (!child_monitor_thread_->Start()) { + NOTREACHED(); + } + + child_monitor_thread_->task_runner()->PostTask( + FROM_HERE, + base::BindOnce(&TorLauncherImpl::MonitorChild, base::Unretained(this))); + } +} + +void TorLauncherImpl::SetCrashHandler(SetCrashHandlerCallback callback) { + crash_handler_callback_ = std::move(callback); +} + +void TorLauncherImpl::Relaunch(const base::FilePath& tor_bin, + const std::string& tor_host, + const std::string& tor_port, + const base::FilePath& tor_data_dir, + const base::FilePath& tor_watch_dir, + RelaunchCallback callback) { + if (tor_process_.IsValid()) + tor_process_.Terminate(0, true); + + tor_process_.WaitForExit(nullptr); + Launch(tor_bin, tor_host, tor_port, tor_data_dir, tor_watch_dir, + std::move(callback)); +} + +void TorLauncherImpl::MonitorChild() { +#if defined(OS_POSIX) + char buf[PIPE_BUF]; + + while (1) { + if (read(pipehack[0], buf, sizeof(buf)) > 0) { + pid_t pid; + int status; + + if ((pid = waitpid(-1, &status, WNOHANG)) != -1) { + if (WIFSIGNALED(status)) { + LOG(ERROR) << "tor got terminated by signal " << WTERMSIG(status); + } else if (WCOREDUMP(status)) { + LOG(ERROR) << "tor coredumped"; + } else if (WIFEXITED(status)) { + LOG(ERROR) << "tor exit (" << WEXITSTATUS(status) << ")"; + } + if (crash_handler_callback_) + std::move(crash_handler_callback_).Run(pid); + } + } else { + // pipes closed + break; + } + } +#elif defined(OS_WIN) + WaitForSingleObject(tor_process_.Handle(), INFINITE); + if (crash_handler_callback_) + std::move(crash_handler_callback_). + Run(base::GetProcId(tor_process_.Handle())); +#else +#error unsupported platforms +#endif +} + +} // namespace brave diff --git a/brave/utility/tor/tor_launcher_impl.h b/brave/utility/tor/tor_launcher_impl.h new file mode 100644 index 0000000000..f1333feb79 --- /dev/null +++ b/brave/utility/tor/tor_launcher_impl.h @@ -0,0 +1,52 @@ +// Copyright (c) 2018 The Brave Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BRAVE_UTILITY_TOR_TOR_LAUNCHER_IMPL_H_ +#define BRAVE_UTILITY_TOR_TOR_LAUNCHER_IMPL_H_ + +#include +#include +#include + +#include "base/macros.h" +#include "base/process/process.h" +#include "brave/common/tor/tor.mojom.h" +#include "mojo/public/cpp/bindings/interface_request.h" +#include "services/service_manager/public/cpp/service_context_ref.h" + +namespace brave { + +class TorLauncherImpl : public tor::mojom::TorLauncher { + public: + explicit TorLauncherImpl( + std::unique_ptr service_ref); + ~TorLauncherImpl() override; + + // tor::mojom::TorLauncher + void Launch(const base::FilePath& tor_bin, + const std::string& tor_host, const std::string& tor_port, + const base::FilePath& tor_data_dir, + const base::FilePath& tor_watch_dir, + LaunchCallback callback) override; + void SetCrashHandler(SetCrashHandlerCallback callback) override; + void Relaunch(const base::FilePath& tor_bin, + const std::string& tor_host, const std::string& tor_port, + const base::FilePath& tor_data_dir, + const base::FilePath& tor_watch_dir, + RelaunchCallback callback) override; + + private: + void MonitorChild(); + + SetCrashHandlerCallback crash_handler_callback_; + std::unique_ptr child_monitor_thread_; + base::Process tor_process_; + const std::unique_ptr service_ref_; + + DISALLOW_COPY_AND_ASSIGN(TorLauncherImpl); +}; + +} // namespace brave + +#endif // BRAVE_UTILITY_TOR_TOR_LAUNCHER_IMPL_H_ diff --git a/brave/utility/tor/tor_manifest.json b/brave/utility/tor/tor_manifest.json new file mode 100644 index 0000000000..f3e14ca88a --- /dev/null +++ b/brave/utility/tor/tor_manifest.json @@ -0,0 +1,15 @@ +{ + "name": "tor_launcher", + "display_name": "Tor Launcher", + "sandbox_type": "none", + "interface_provider_specs": { + "service_manager:connector": { + "provides": { + "tor_launcher": [ "tor::mojom::TorLauncher" ] + }, + "requires": { + "service_manager": [ "service_manager:all_users" ] + } + } + } +} diff --git a/brave/utility/tor/tor_service.cc b/brave/utility/tor/tor_service.cc new file mode 100644 index 0000000000..a6d715fb27 --- /dev/null +++ b/brave/utility/tor/tor_service.cc @@ -0,0 +1,46 @@ +// Copyright (c) 2018 The Brave Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "brave/utility/tor/tor_service.h" + +#include + +#include "build/build_config.h" +#include "brave/utility/tor/tor_launcher_impl.h" +#include "mojo/public/cpp/bindings/strong_binding.h" + +namespace { + +void OnTorLauncherRequest( + service_manager::ServiceContextRefFactory* ref_factory, + tor::mojom::TorLauncherRequest request) { + mojo::MakeStrongBinding( + std::make_unique(ref_factory->CreateRef()), + std::move(request)); +} + +} // namespace + +TorService::TorService() {} + +TorService::~TorService() {} + +std::unique_ptr +TorService::CreateService() { + return std::make_unique(); +} + +void TorService::OnStart() { + ref_factory_.reset(new service_manager::ServiceContextRefFactory( + context()->CreateQuitClosure())); + registry_.AddInterface( + base::Bind(&OnTorLauncherRequest, ref_factory_.get())); +} + +void TorService::OnBindInterface( + const service_manager::BindSourceInfo& source_info, + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) { + registry_.BindInterface(interface_name, std::move(interface_pipe)); +} diff --git a/brave/utility/tor/tor_service.h b/brave/utility/tor/tor_service.h new file mode 100644 index 0000000000..f1ee857514 --- /dev/null +++ b/brave/utility/tor/tor_service.h @@ -0,0 +1,37 @@ +// Copyright (c) 2018 The Brave Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BRAVE_UTILITY_TOR_TOR_SERVICE_H_ +#define BRAVE_UTILITY_TOR_TOR_SERVICE_H_ + +#include +#include + +#include "services/service_manager/public/cpp/binder_registry.h" +#include "services/service_manager/public/cpp/service_context.h" +#include "services/service_manager/public/cpp/service_context_ref.h" + +class TorService : public service_manager::Service { + public: + TorService(); + ~TorService() override; + + // Factory method for creating the service. + static std::unique_ptr CreateService(); + + // Lifescycle events that occur after the service has started to spinup. + void OnStart() override; + void OnBindInterface(const service_manager::BindSourceInfo& source_info, + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) override; + + private: + // State needed to manage service lifecycle and lifecycle of bound clients. + std::unique_ptr ref_factory_; + service_manager::BinderRegistry registry_; + + DISALLOW_COPY_AND_ASSIGN(TorService); +}; + +#endif // BRAVE_UTILITY_TOR_TOR_SERVICE_H_ diff --git a/chromium_src/chrome/browser/profiles/profile_manager.cc b/chromium_src/chrome/browser/profiles/profile_manager.cc index 185761c84c..729053b952 100644 --- a/chromium_src/chrome/browser/profiles/profile_manager.cc +++ b/chromium_src/chrome/browser/profiles/profile_manager.cc @@ -23,6 +23,7 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/trace_event/trace_event.h" +#include "brave/browser/brave_browser_context.h" #include "build/build_config.h" #include "atom/browser/atom_browser_context.h" #include "chrome/browser/browser_process.h" @@ -82,7 +83,10 @@ void ProfileManager::OnProfileCreated(Profile* profile, bool success, bool is_new_profile) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (!profile->IsOffTheRecord() && + auto brave_browser_context = + brave::BraveBrowserContext::FromBrowserContext(profile); + if ((!profile->IsOffTheRecord() || + brave_browser_context->IsIsolatedStorage()) && !GetProfileByPath(profile->GetPath())) { AddProfile(profile); } diff --git a/lib/browser/api/extensions.js b/lib/browser/api/extensions.js index debacd5385..28ee34a04a 100644 --- a/lib/browser/api/extensions.js +++ b/lib/browser/api/extensions.js @@ -224,7 +224,10 @@ const createTab = function (createProperties, cb) { if (!error && createProperties.partition) { // createProperties.partition always takes precendence ses = session.fromPartition(createProperties.partition, { - parent_partition: createProperties.parent_partition + parent_partition: createProperties.parent_partition, + isolated_storage: createProperties.isolated_storage, + tor_proxy: createProperties.tor_proxy, + tor_path: createProperties.tor_path, }) // don't pass the partition info through delete createProperties.partition diff --git a/patches/master_patch.patch b/patches/master_patch.patch index 9a65688dcc..fef9c7d6cd 100644 --- a/patches/master_patch.patch +++ b/patches/master_patch.patch @@ -114,8 +114,20 @@ index 4304cc82494f57b7bbc4d1f3dff0fab96e30aef3..77130b344ba1e03e34e5faa752cd2590 } assert(!is_ios, "Chromium/iOS shouldn't use anything in //chrome") +diff --git a/chrome/app/BUILD.gn b/chrome/app/BUILD.gn +index e5744a9d05d3099a61815954b08c7c030d081071..1dfade8ab95643acb19ebf39ae9b69506fbeb5e6 100644 +--- a/chrome/app/BUILD.gn ++++ b/chrome/app/BUILD.gn +@@ -424,6 +424,7 @@ if (is_win) { + if (!is_android) { + chrome_packaged_services += [ "//chrome/utility:profile_import_manifest" ] + } ++chrome_packaged_services += [ "//electron/app:tor_launcher_manifest" ] + + service_manifest("chrome_manifest") { + source = "chrome_manifest.json" diff --git a/chrome/browser/chrome_content_browser_manifest_overlay.json b/chrome/browser/chrome_content_browser_manifest_overlay.json -index cd82cd63bfff860abdd765ad6e35355caffc3a43..9d24c0c3a7b315c10b519e0ae5b0eea04a880ddc 100644 +index cd82cd63bfff860abdd765ad6e35355caffc3a43..eb8966b82071f04263e00c897a8708eb9ff6ec91 100644 --- a/chrome/browser/chrome_content_browser_manifest_overlay.json +++ b/chrome/browser/chrome_content_browser_manifest_overlay.json @@ -12,7 +12,7 @@ @@ -127,6 +139,14 @@ index cd82cd63bfff860abdd765ad6e35355caffc3a43..9d24c0c3a7b315c10b519e0ae5b0eea0 "safe_browsing::mojom::SafeBrowsing", "translate::mojom::ContentTranslateDriver" ], +@@ -55,6 +55,7 @@ + "proxy_resolver": [ "factory" ], + "preferences": [ "pref_client", "pref_control" ], + "removable_storage_writer": [ "removable_storage_writer" ], ++ "tor_launcher": [ "tor_launcher" ], + "ui": [ + "display_dev", + "ime_registrar", diff --git a/chrome/browser/chrome_service.cc b/chrome/browser/chrome_service.cc index a6e8369996c9538a1969a8eef3091c00eecb5ec1..eff895a8593ad0edaaa6e38e1c6f013af5fb3c46 100644 --- a/chrome/browser/chrome_service.cc @@ -1317,6 +1337,25 @@ index b1d214c35f075d16acfcd71576842e6b751d0697..8e9fb9fc6f5d27a106b13aad0412fc84 DCHECK(from_rfh); FrameTreeNode* node = static_cast(from_rfh)->frame_tree_node(); +diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc +index d938013c90b630b94c2f4ee2daed542dbe437da0..05fbfe707db8afb0dcf4d3fa1a841c506e8c470c 100644 +--- a/content/browser/frame_host/render_frame_host_impl.cc ++++ b/content/browser/frame_host/render_frame_host_impl.cc +@@ -2952,9 +2952,13 @@ void RenderFrameHostImpl::CreateNewWindow( + return; + } + ++ scoped_refptr site_instance = ++ params->opener_suppressed ++ ? SiteInstance::CreateForURL(GetProcess()->GetBrowserContext(), params->target_url) ++ : GetSiteInstance(); + // This will clone the sessionStorage for namespace_id_to_clone. + StoragePartition* storage_partition = BrowserContext::GetStoragePartition( +- GetSiteInstance()->GetBrowserContext(), GetSiteInstance()); ++ site_instance->GetBrowserContext(), site_instance.get()); + DOMStorageContextWrapper* dom_storage_context = + static_cast( + storage_partition->GetDOMStorageContext()); diff --git a/content/browser/frame_host/render_frame_message_filter.cc b/content/browser/frame_host/render_frame_message_filter.cc index 80fd7cf8957865e62186f394a318f912c6da4e20..a189c82b5a2d6ca6fdfb38c6eadffebd518999ea 100644 --- a/content/browser/frame_host/render_frame_message_filter.cc @@ -1619,6 +1658,40 @@ index 9e0e5b96b8e38a6c29e601d091941dad28eec900..1463daf2462cfb3d8208a91f3fb3b0f1 } void RenderWidgetTargeter::ViewWillBeDestroyed(RenderWidgetHostViewBase* view) { +diff --git a/content/browser/storage_partition_impl_map.h b/content/browser/storage_partition_impl_map.h +index ce0951bacd4dab08db92f6a87087279fcc7e4f09..d0195f20c4f05b406521bbe6e29a792454246713 100644 +--- a/content/browser/storage_partition_impl_map.h ++++ b/content/browser/storage_partition_impl_map.h +@@ -21,6 +21,7 @@ namespace base { + class FilePath; + class SequencedTaskRunner; + } // namespace base ++namespace brave {class BraveBrowserContext;} // namespace brave + + namespace content { + +@@ -64,6 +65,8 @@ class CONTENT_EXPORT StoragePartitionImplMap + FRIEND_TEST_ALL_PREFIXES(StoragePartitionConfigTest, OperatorLess); + FRIEND_TEST_ALL_PREFIXES(StoragePartitionImplMapTest, GarbageCollect); + ++ friend class brave::BraveBrowserContext; ++ + // Each StoragePartition is uniquely identified by which partition domain + // it belongs to (such as an app or the browser itself), the user supplied + // partition name and the bit indicating whether it should be persisted on +diff --git a/content/browser/utility_process_host.cc b/content/browser/utility_process_host.cc +index 39b89cd36c327f27da7f687c3179ace964fc6d63..9140ff961245e4e4e222986e4829790663fad920 100644 +--- a/content/browser/utility_process_host.cc ++++ b/content/browser/utility_process_host.cc +@@ -300,6 +300,8 @@ bool UtilityProcessHost::StartProcess() { + if (is_service) { + GetContentClient()->browser()->AdjustUtilityServiceProcessCommandLine( + *service_identity_, cmd_line.get()); ++ if (service_identity_->name() == "tor_launcher") ++ cmd_line->AppendSwitch("tor-launcher"); + } + + process_->Launch(std::make_unique( diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 942a35d355acc1cff8762c1e5a4961c6f022f4b2..182887b23f1b8b969cf68302673a7f94139b7ba3 100644 --- a/content/browser/web_contents/web_contents_impl.cc @@ -1688,6 +1761,18 @@ index cec3bd8a97b8b9bcab176a9bd2c296ec12aba838..a00a391c96fc1f04be189c41cb285a66 - (bool)isValidDragTarget:(content::RenderWidgetHostImpl*)targetRWH { return targetRWH->GetProcess()->GetID() == dragStartProcessID_ || GetRenderViewHostID(webContents_->GetRenderViewHost()) != +diff --git a/content/child/child_thread_impl.cc b/content/child/child_thread_impl.cc +index 2663268bce314609bb8ec66830a873579ec139fe..b956eaed8938a063279a8d384d605437b5a7372c 100644 +--- a/content/child/child_thread_impl.cc ++++ b/content/child/child_thread_impl.cc +@@ -535,6 +535,7 @@ void ChildThreadImpl::Init(const Options& options) { + // Check that --process-type is specified so we don't do this in unit tests + // and single-process mode. + if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessType)) ++ if (!base::CommandLine::ForCurrentProcess()->HasSwitch("tor-launcher")) + channel_->AddFilter(new SuicideOnChannelErrorFilter()); + #endif + diff --git a/content/common/content_switches_internal.cc b/content/common/content_switches_internal.cc index 27c25d3d25e18d9591b6ffd770fcd11875b231f7..01d2b4c88bf1c6f25441f7cd219e56df401f18f6 100644 --- a/content/common/content_switches_internal.cc @@ -2141,10 +2226,10 @@ index 3802937bc0c472cb72d38958ccbe9d5b25da6cbb..79f05f7f57f2547b50c9755dd363ab47 } diff --git a/net/log/net_log_event_type_list.h b/net/log/net_log_event_type_list.h -index e23f2e6e9d9deb5fcd93f39c0e88c63ead47ac87..5c3e259474eec476038ee70bc90d6f0d188d84bd 100644 +index 596c35c5be6a443a33d1b36587a34ef58debad68..583ff6dd9abeb39dd7e6bed43caf323ba299d838 100644 --- a/net/log/net_log_event_type_list.h +++ b/net/log/net_log_event_type_list.h -@@ -2118,6 +2118,12 @@ EVENT_TYPE(SOCKS5_GREET_WRITE) +@@ -2115,6 +2115,12 @@ EVENT_TYPE(SOCKS5_GREET_WRITE) // The time spent waiting for the "greeting" response from the SOCKS server. EVENT_TYPE(SOCKS5_GREET_READ) @@ -2312,6 +2397,20 @@ index 389315a25d7da30d71b59e3803ab795bc4c18e1c..79797fe7e674f9f6d2a65de542f262a9 // Called to read raw (pre-filtered) data from this Job. Reads at most // |buf_size| bytes into |buf|. // Possible return values: +diff --git a/services/service_manager/sandbox/win/sandbox_win.cc b/services/service_manager/sandbox/win/sandbox_win.cc +index 50430a8e2f8fc30e08412e75299be7d4ca275252..b65147fc394d96a0557f1987a4f4e8dc14328b44 100644 +--- a/services/service_manager/sandbox/win/sandbox_win.cc ++++ b/services/service_manager/sandbox/win/sandbox_win.cc +@@ -827,6 +827,9 @@ sandbox::ResultCode SandboxWin::StartSandboxedProcess( + service_manager::switches::kNoSandbox)) { + base::LaunchOptions options; + options.handles_to_inherit = handles_to_inherit; ++#if !defined(MUON_CHROMIUM_BUILD) ++ options.start_hidden = true; ++#endif + *process = base::LaunchProcess(*cmd_line, options); + return sandbox::SBOX_ALL_OK; + } diff --git a/third_party/blink/renderer/core/editing/editing_behavior.h b/third_party/blink/renderer/core/editing/editing_behavior.h index 90f13baf5daa216c0832b39137ba87f60aa2ccd2..643caf4e6825e3da6678af6a1a981c42d2bb782b 100644 --- a/third_party/blink/renderer/core/editing/editing_behavior.h diff --git a/vendor/brightray/browser/browser_context.cc b/vendor/brightray/browser/browser_context.cc index 9c0dc3a5e6..c6de88e96f 100644 --- a/vendor/brightray/browser/browser_context.cc +++ b/vendor/brightray/browser/browser_context.cc @@ -125,7 +125,7 @@ net::URLRequestContextGetter* BrowserContext::CreateRequestContext( this, static_cast(BrowserClient::Get()->GetNetLog()), GetPath(), - in_memory_, + IsOffTheRecord(), BrowserThread::GetTaskRunnerForThread(BrowserThread::IO), protocol_handlers, std::move(protocol_interceptors)); @@ -174,25 +174,9 @@ content::BackgroundSyncController* BrowserContext::GetBackgroundSyncController() return nullptr; } -net::URLRequestContextGetter* -BrowserContext::CreateRequestContextForStoragePartition( - const base::FilePath& partition_path, - bool in_memory, - content::ProtocolHandlerMap* protocol_handlers, - content::URLRequestInterceptorScopedVector request_interceptors) { - return nullptr; -} - net::URLRequestContextGetter* BrowserContext::CreateMediaRequestContext() { return url_request_getter_.get(); } -net::URLRequestContextGetter* -BrowserContext::CreateMediaRequestContextForStoragePartition( - const base::FilePath& partition_path, - bool in_memory) { - return nullptr; -} - } // namespace brightray diff --git a/vendor/brightray/browser/browser_context.h b/vendor/brightray/browser/browser_context.h index 0caf81b5f0..9c3ddfbb6e 100644 --- a/vendor/brightray/browser/browser_context.h +++ b/vendor/brightray/browser/browser_context.h @@ -47,15 +47,7 @@ class BrowserContext : public content::BrowserContext, net::URLRequestContextGetter* CreateRequestContext( content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors) override; - net::URLRequestContextGetter* CreateRequestContextForStoragePartition( - const base::FilePath& partition_path, - bool in_memory, - content::ProtocolHandlerMap* protocol_handlers, - content::URLRequestInterceptorScopedVector request_interceptors) override; net::URLRequestContextGetter* CreateMediaRequestContext() override; - net::URLRequestContextGetter* CreateMediaRequestContextForStoragePartition( - const base::FilePath& partition_path, - bool in_memory) override; URLRequestContextGetter* url_request_context_getter() const { return url_request_getter_.get();