Skip to content
This repository has been archived by the owner on Jan 4, 2019. It is now read-only.

Commit

Permalink
Use network delegate to intercept every requests and apply proxy config
Browse files Browse the repository at this point in the history
  • Loading branch information
darkdh committed Jun 27, 2018
1 parent b486e40 commit 692e7c9
Show file tree
Hide file tree
Showing 9 changed files with 200 additions and 78 deletions.
18 changes: 10 additions & 8 deletions atom/browser/extensions/atom_extensions_network_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -57,8 +61,6 @@ class AtomExtensionsNetworkDelegate : public atom::AtomNetworkDelegate {
const net::HttpResponseHeaders* original_response_headers,
scoped_refptr<net::HttpResponseHeaders>* 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,
Expand Down
2 changes: 2 additions & 0 deletions brave/browser/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ source_set("proxy") {
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 = [
Expand Down
33 changes: 18 additions & 15 deletions brave/browser/brave_browser_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include "base/trace_event/trace_event.h"
#include "brave/browser/brave_permission_manager.h"
#include "brave/browser/tor/tor_launcher_factory.h"
#include "brave/browser/net/proxy_resolution/proxy_config_service_tor.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"
Expand Down Expand Up @@ -372,14 +372,6 @@ BraveBrowserContext::CreateRequestContextForStoragePartition(
url_request_context_getter->GetURLRequestContext()
->set_network_delegate(default_network_delegate);
url_request_context_getter_map_[descriptor] = url_request_context_getter;
if (tor_proxy_.size()) {
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&net::ProxyConfigServiceTor::TorSetProxy,
url_request_context_getter,
tor_proxy_,
isolated_storage_,
partition_path));
}
return url_request_context_getter.get();
} else {
return nullptr;
Expand Down Expand Up @@ -484,9 +476,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<net::URLRequestJobFactory>
Expand Down Expand Up @@ -748,9 +745,15 @@ void BraveBrowserContext::SetTorNewIdentity(const GURL& url,
auto proxy_resolution_service =
url_request_context_getter->GetURLRequestContext()->
proxy_resolution_service();
proxy_resolution_service->ForceReloadProxyConfig();
if (callback)
callback.Run();
BrowserThread::PostTaskAndReply(
BrowserThread::IO, FROM_HERE,
base::Bind(&net::ProxyConfigServiceTor::TorSetProxy,
proxy_resolution_service,
tor_proxy_,
host,
&tor_proxy_map_,
true),
callback);
}

scoped_refptr<base::SequencedTaskRunner>
Expand Down
8 changes: 8 additions & 0 deletions brave/browser/brave_browser_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <vector>

#include "atom/browser/atom_browser_context.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"
Expand Down Expand Up @@ -146,6 +147,11 @@ class BraveBrowserContext : public Profile {

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_; }

private:
typedef std::map<StoragePartitionDescriptor,
scoped_refptr<brightray::URLRequestContextGetter>,
Expand Down Expand Up @@ -177,6 +183,8 @@ class BraveBrowserContext : public Profile {
bool in_memory_;
std::string tor_proxy_;

net::ProxyConfigServiceTor::TorProxyMap tor_proxy_map_;

URLRequestContextGetterMap url_request_context_getter_map_;

std::unique_ptr<WebDataServiceWrapper> web_database_wrapper_;
Expand Down
59 changes: 29 additions & 30 deletions brave/browser/net/proxy_resolution/proxy_config_service_tor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ using content::BrowserThread;
const int kTorPasswordLength = 16;

ProxyConfigServiceTor::ProxyConfigServiceTor(
const std::string& tor_proxy) {
const std::string& tor_proxy, const std::string& username,
TorProxyMap* tor_proxy_map) {
if (tor_proxy.length()) {
url::Parsed url;
url::ParseStandardURL(
Expand All @@ -50,53 +51,51 @@ ProxyConfigServiceTor::ProxyConfigServiceTor(
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()) {
auto found = tor_proxy_map->find(username);
std::string password;
if (found == tor_proxy_map->end()) {
password = GenerateNewPassword();
tor_proxy_map->insert(std::pair<std::string, std::string>(username,
password));
} else {
password = found->second;
}
proxy_url = std::string(scheme_ + "://" + username + ":" + password +
"@" + host_ + ":" + port_);
} else {
proxy_url = std::string(scheme_ + "://" + host_ + ":" + port_);
}
config_.proxy_rules().ParseFromString(proxy_url);
}
config_.proxy_rules().ParseFromString(std::string(scheme_ + "://" + host_
+ ":" + port_));
}

ProxyConfigServiceTor::~ProxyConfigServiceTor() {}

void ProxyConfigServiceTor::TorSetProxy(
scoped_refptr<brightray::URLRequestContextGetter>
url_request_context_getter,
const std::string tor_proxy,
const bool isolated_storage,
const base::FilePath partition_path) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!url_request_context_getter || !isolated_storage)
net::ProxyResolutionService* service,
const std::string& tor_proxy,
const std::string& site_url,
TorProxyMap* tor_proxy_map,
bool new_password) {
if (!service)
return;
auto proxy_service = url_request_context_getter->GetURLRequestContext()->
proxy_resolution_service();
// Notice CreateRequestContextForStoragePartition will only be called once
// per partition_path so there is no need to cache password per origin
std::string origin = partition_path.DirName().BaseName().AsUTF8Unsafe();
if (new_password && tor_proxy_map)
tor_proxy_map->erase(site_url);
std::unique_ptr<net::ProxyConfigServiceTor>
config(new ProxyConfigServiceTor(tor_proxy));
config->SetUsername(origin);
proxy_service->ResetConfigService(std::move(config));
config(new ProxyConfigServiceTor(tor_proxy, site_url, tor_proxy_map));
service->ResetConfigService(std::move(config));
}

ProxyConfigServiceTor::ConfigAvailability
ProxyConfigServiceTor::GetLatestProxyConfig(ProxyConfig* config) {
if (scheme_ != kSocksProxy || host_.empty() || port_.empty())
return CONFIG_UNSET;
std::string password = GenerateNewPassword();
std::string url = std::string(scheme_ + "://" + username_ + ":" + password +
"@" + host_ + ":" + port_);
config_.proxy_rules().ParseFromString(url);
*config = config_;
return CONFIG_VALID;
}

bool ProxyConfigServiceTor::SetUsername(const std::string& username) {
if (username.empty())
return false;
username_ = username;
return true;
}


std::string ProxyConfigServiceTor::GenerateNewPassword() {
std::vector<uint8_t> password(kTorPasswordLength);
crypto::RandBytes(password.data(), password.size());
Expand Down
22 changes: 12 additions & 10 deletions brave/browser/net/proxy_resolution/proxy_config_service_tor.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define BRAVE_BROWSER_NET_PROXY_RESOLUTION_PROXY_CONFIG_SERVICE_TOR_H_

#include <string>
#include <map>

#include "base/compiler_specific.h"
#include "net/base/net_errors.h"
Expand All @@ -21,24 +22,26 @@ const char kSocksProxy[] = "socks5";
// Implementation of ProxyConfigService that returns a tor specific result.
class NET_EXPORT ProxyConfigServiceTor : public ProxyConfigService {
public:
explicit ProxyConfigServiceTor(const std::string& tor_proxy);
// Used to cache <username, password> of proxies
typedef std::map<std::string, std::string> TorProxyMap;

explicit ProxyConfigServiceTor(const std::string& tor_proxy,
const std::string& username,
TorProxyMap* map);
~ProxyConfigServiceTor() override;

static void TorSetProxy(
scoped_refptr<brightray::URLRequestContextGetter>
url_request_context_getter,
const std::string tor_proxy,
const bool isolated_storage,
const base::FilePath partition_path);
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(ProxyConfig* config) override;

// Set origin as username
bool SetUsername(const std::string& username);

private:
// Generate a new 128 bit random tag
std::string GenerateNewPassword();
Expand All @@ -48,7 +51,6 @@ class NET_EXPORT ProxyConfigServiceTor : public ProxyConfigService {
std::string scheme_;
std::string host_;
std::string port_;
std::string username_;
};

} // namespace net
Expand Down
74 changes: 74 additions & 0 deletions brave/browser/net/tor_proxy_network_delegate.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// 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<BraveBrowserContext*>(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))
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
Loading

0 comments on commit 692e7c9

Please sign in to comment.