summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authoridanan@chromium.org <idanan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-23 18:02:23 +0000
committeridanan@chromium.org <idanan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-23 18:02:23 +0000
commiteaadd905fd0d3e3e0496f229a5aaa3e3982002a4 (patch)
tree7174b1009f01eb2ee982c1d834c4d052ff916904 /chrome/browser
parentc86d472e35440254cf860f40c40aaaf45992bfdc (diff)
downloadchromium_src-eaadd905fd0d3e3e0496f229a5aaa3e3982002a4.zip
chromium_src-eaadd905fd0d3e3e0496f229a5aaa3e3982002a4.tar.gz
chromium_src-eaadd905fd0d3e3e0496f229a5aaa3e3982002a4.tar.bz2
Privacy Blacklist SketelonAdded code hooks to serve as place holders for the implementationof the privacy blacklist. The --privacy-blacklist option was addedwhich will eventually is used to activate the code.This is work-in-progress code which effectively makes a couple morepointer-checks when the --privacy-blacklist is not specified. Whenit is specified, some of the blacklist code is executed but theblacklist is always empty and therefore has no impact on browsing.
BUG=none TEST=Blacklist* Review URL: http://codereview.chromium.org/119313 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@19033 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/net/chrome_url_request_context.cc35
-rw-r--r--chrome/browser/net/chrome_url_request_context.h6
-rw-r--r--chrome/browser/privacy_blacklist/blacklist.cc72
-rw-r--r--chrome/browser/privacy_blacklist/blacklist.h130
-rw-r--r--chrome/browser/privacy_blacklist/blacklist_unittest.cc29
-rw-r--r--chrome/browser/profile.cc26
-rw-r--r--chrome/browser/profile.h7
-rw-r--r--chrome/browser/renderer_host/resource_dispatcher_host.cc20
8 files changed, 323 insertions, 2 deletions
diff --git a/chrome/browser/net/chrome_url_request_context.cc b/chrome/browser/net/chrome_url_request_context.cc
index b188694..1e01821 100644
--- a/chrome/browser/net/chrome_url_request_context.cc
+++ b/chrome/browser/net/chrome_url_request_context.cc
@@ -7,6 +7,7 @@
#include "base/command_line.h"
#include "base/string_util.h"
#include "chrome/browser/browser_process.h"
+#include "chrome/browser/privacy_blacklist/blacklist.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/extensions/user_script_master.h"
@@ -23,6 +24,7 @@
#include "net/http/http_network_layer.h"
#include "net/http/http_util.h"
#include "net/proxy/proxy_service.h"
+#include "net/url_request/url_request.h"
#include "webkit/glue/webkit_glue.h"
net::ProxyConfig* CreateProxyConfig(const CommandLine& command_line) {
@@ -287,6 +289,8 @@ ChromeURLRequestContext::ChromeURLRequestContext(Profile* profile)
cookie_policy_.SetType(net::CookiePolicy::FromInt(
prefs_->GetInteger(prefs::kCookieBehavior)));
+ blacklist_ = profile->GetBlacklist();
+
force_tls_state_ = profile->GetForceTLSState();
if (profile->GetExtensionsService()) {
@@ -380,6 +384,37 @@ const std::string& ChromeURLRequestContext::GetUserAgent(
return webkit_glue::GetUserAgent(url);
}
+bool ChromeURLRequestContext::interceptCookie(const URLRequest* request,
+ std::string* cookie) {
+ const URLRequest::UserData* d =
+ request->GetUserData((void*)&Blacklist::kRequestDataKey);
+ if (d) {
+ const Blacklist::Entry* entry =
+ static_cast<const Blacklist::RequestData*>(d)->entry();
+ if (entry->attributes() & Blacklist::kDontStoreCookies) {
+ cookie->clear();
+ return false;
+ }
+ if (entry->attributes() & Blacklist::kDontPersistCookies) {
+ *cookie = Blacklist::StripCookieExpiry(*cookie);
+ }
+ }
+ return true;
+}
+
+bool ChromeURLRequestContext::allowSendingCookies(const URLRequest* request)
+ const {
+ const URLRequest::UserData* d =
+ request->GetUserData((void*)&Blacklist::kRequestDataKey);
+ if (d) {
+ const Blacklist::Entry* entry =
+ static_cast<const Blacklist::RequestData*>(d)->entry();
+ if (entry->attributes() & Blacklist::kDontSendCookies)
+ return false;
+ }
+ return true;
+}
+
void ChromeURLRequestContext::OnAcceptLanguageChange(
std::string accept_language) {
DCHECK(MessageLoop::current() ==
diff --git a/chrome/browser/net/chrome_url_request_context.h b/chrome/browser/net/chrome_url_request_context.h
index bf8d119..6e7d122 100644
--- a/chrome/browser/net/chrome_url_request_context.h
+++ b/chrome/browser/net/chrome_url_request_context.h
@@ -65,7 +65,11 @@ class ChromeURLRequestContext : public URLRequestContext,
virtual const std::string& GetUserAgent(const GURL& url) const;
- private:
+ virtual bool interceptCookie(const URLRequest* request, std::string* cookie);
+
+ virtual bool allowSendingCookies(const URLRequest* request) const;
+
+private:
// Private constructor, use the static factory methods instead. This is
// expected to be called on the UI thread.
ChromeURLRequestContext(Profile* profile);
diff --git a/chrome/browser/privacy_blacklist/blacklist.cc b/chrome/browser/privacy_blacklist/blacklist.cc
new file mode 100644
index 0000000..8b575a8
--- /dev/null
+++ b/chrome/browser/privacy_blacklist/blacklist.cc
@@ -0,0 +1,72 @@
+// Copyright (c) 2009 The Chromium 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 "chrome/browser/privacy_blacklist/blacklist.h"
+
+#include <algorithm>
+#include <string>
+
+namespace {
+
+bool matches(std::string pattern, std::string url) {
+ return url.find(pattern) != std::string::npos;
+}
+
+}
+
+// Value is not important, here just that the object has an address.
+const void* const Blacklist::kRequestDataKey = 0;
+
+bool Blacklist::Entry::MatchType(const std::string& type) const {
+ return std::find(types_->begin(), types_->end(), type) != types_->end();
+}
+
+bool Blacklist::Entry::IsBlocked(const GURL& url) const {
+ return (attributes_ & kBlockAll) ||
+ ((attributes_ & kBlockUnsecure) && !url.SchemeIsSecure());
+}
+
+Blacklist::Entry::Entry(const std::string& pattern, unsigned int attributes)
+ : pattern_(pattern), attributes_(attributes) {}
+
+void Blacklist::Entry::AddType(const std::string& type) {
+ types_->push_back(type);
+}
+
+Blacklist::Blacklist(const FilePath& file) {
+ // TODO(idanan): Do something here.
+}
+
+Blacklist::~Blacklist() {
+ for (std::vector<Entry*>::iterator i = blacklist_.begin();
+ i != blacklist_.end(); ++i)
+ delete *i;
+}
+
+// Returns a pointer to the Blacklist-owned entry which matches the given
+// URL. If no matching Entry is found, returns null.
+const Blacklist::Entry* Blacklist::findMatch(const GURL& url) const {
+ for (std::vector<Entry*>::const_iterator i = blacklist_.begin();
+ i != blacklist_.end(); ++i)
+ if (matches((*i)->pattern(), url.spec()))
+ return *i;
+ return 0;
+}
+
+std::string Blacklist::StripCookies(const std::string& header) {
+ // TODO(idanan): Implement this.
+ return header;
+}
+
+std::string Blacklist::StripCookieExpiry(const std::string& cookie) {
+ std::string::size_type start = cookie.find("; expires=");
+ if (start != std::string::npos) {
+ std::string::size_type finish = cookie.find(";", start+1);
+ std::string session_cookie(cookie, 0, start);
+ if (finish != std::string::npos)
+ session_cookie.append(cookie.substr(finish));
+ return session_cookie;
+ }
+ return cookie;
+}
diff --git a/chrome/browser/privacy_blacklist/blacklist.h b/chrome/browser/privacy_blacklist/blacklist.h
new file mode 100644
index 0000000..f3f49ea
--- /dev/null
+++ b/chrome/browser/privacy_blacklist/blacklist.h
@@ -0,0 +1,130 @@
+// Copyright (c) 2009 The Chromium 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 CHROME_BROWSER_PRIVACY_BLACKLIST_BLACKLIST_H_
+#define CHROME_BROWSER_PRIVACY_BLACKLIST_BLACKLIST_H_
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/scoped_ptr.h"
+#include "googleurl/src/gurl.h"
+#include "net/url_request/url_request.h"
+
+class FilePath;
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Blacklist Class
+//
+// Represents a blacklist used to protect user from privacy and annoyances.
+// A blacklist is essentially a map from resource-match patterns to filter-
+// attributes. Each time a resources matches a pattern the filter-attributes
+// are used to determine how the browser handles the matching resource.
+//
+// TODO(idanan): Implement this efficiently.
+// To get things started, the initial implementation is as simple as
+// it gets and cannot scale to large blacklists but it should be enough
+// for testing on the order of a hundred or so entries.
+//
+////////////////////////////////////////////////////////////////////////////////
+class Blacklist {
+ public:
+ // Filter attributes (more to come):
+ static const unsigned int kBlockAll = 1;
+ static const unsigned int kDontSendCookies = 1 << 1;
+ static const unsigned int kDontStoreCookies = 1 << 2;
+ static const unsigned int kDontPersistCookies = 1 << 3;
+ static const unsigned int kDontSendReferrer = 1 << 4;
+ static const unsigned int kDontSendUserAgent = 1 << 5;
+ static const unsigned int kBlockByType = 1 << 6;
+ static const unsigned int kBlockUnsecure = 1 << 7;
+
+ // Aggregate filter types:
+ static const unsigned int kBlockRequest = kBlockAll | kBlockUnsecure;
+ static const unsigned int kBlockResponse = kBlockByType;
+ static const unsigned int kModifySentHeaders =
+ kDontSendCookies | kDontSendUserAgent | kDontSendReferrer;
+ static const unsigned int kModifyReceivedHeaders =
+ kDontPersistCookies | kDontStoreCookies;
+ static const unsigned int kFilterByHeaders = kModifyReceivedHeaders |
+ kBlockByType;
+
+ // Key used to access data attached to URLRequest objects.
+ static const void* const kRequestDataKey;
+
+ // A single blacklist entry which is returned when a URL matches one of
+ // the patterns. Entry objects are owned by the Blacklist that stores them.
+ class Entry {
+ public:
+ // Returns the pattern which this entry matches.
+ const std::string& pattern() const { return pattern_; }
+
+ // Bitfield of filter-attributes matching the pattern.
+ unsigned int attributes() const { return attributes_; }
+
+ // Returns true if the given type matches one of the types for which
+ // the filter-attributes of this pattern apply. This needs only to be
+ // checked for content-type specific rules, as determined by calling
+ // attributes().
+ bool MatchType(const std::string&) const;
+
+ // Returns true of the given URL is blocked, assumes it matches the
+ // pattern of this entry.
+ bool IsBlocked(const GURL&) const;
+
+ private:
+ Entry(const std::string& pattern, unsigned int attributes);
+ void AddType(const std::string& type);
+
+ std::string pattern_;
+ unsigned int attributes_;
+ scoped_ptr< std::vector<std::string> > types_;
+
+ friend class Blacklist; // Only Blacklist can create an entry.
+ };
+
+ // When a request matches a Blacklist rule but the rule must be applied
+ // after the request has started, we tag it with this user data to
+ // avoid doing lookups more than once per request. The Entry is owned
+ // be the blacklist, so this indirection makes sure that it does not
+ // get destroyed by the Blacklist.
+ class RequestData : public URLRequest::UserData {
+ public:
+ explicit RequestData(const Entry* entry) : entry_(entry) {}
+ const Entry* entry() const { return entry_; }
+ private:
+ const Entry* const entry_;
+ };
+
+ // Constructs a Blacklist given the filename of the persistent version.
+ //
+ // For startup efficiency, and because the blacklist must be available
+ // before any http request is made (including the homepage, if one is
+ // set to be loaded at startup), it is important to load the blacklist
+ // from a local source as efficiently as possible. For this reason, the
+ // combined rules from all active blacklists are stored in one local file.
+ explicit Blacklist(const FilePath& path);
+
+ // Destructor.
+ ~Blacklist();
+
+ // Returns a pointer to the Blacklist-owned entry which matches the given
+ // URL. If no matching Entry is found, returns null.
+ const Entry* findMatch(const GURL&) const;
+
+ // Helper to remove cookies from a header.
+ static std::string StripCookies(const std::string&);
+
+ // Helper to remove cookie expiration from a header.
+ static std::string StripCookieExpiry(const std::string&);
+
+ private:
+ std::vector<Entry*> blacklist_;
+
+ DISALLOW_COPY_AND_ASSIGN(Blacklist);
+};
+
+#endif
diff --git a/chrome/browser/privacy_blacklist/blacklist_unittest.cc b/chrome/browser/privacy_blacklist/blacklist_unittest.cc
new file mode 100644
index 0000000..ad363ad
--- /dev/null
+++ b/chrome/browser/privacy_blacklist/blacklist_unittest.cc
@@ -0,0 +1,29 @@
+// Copyright (c) 2009 The Chromium 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 "chrome/browser/privacy_blacklist/blacklist.h"
+#include "base/file_path.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+TEST(BlacklistTest, Generic) {
+ FilePath path;
+ Blacklist blacklist(path);
+
+ // Empty blacklist should not match any URL.
+ EXPECT_FALSE(blacklist.findMatch(GURL()));
+ EXPECT_FALSE(blacklist.findMatch(GURL("http://www.google.com")));
+
+ std::string cookie1(
+ "PREF=ID=14a549990453e42a:TM=1245183232:LM=1245183232:S=Occ7khRVIEE36Ao5;"
+ " expires=Thu, 16-Jun-2011 20:13:52 GMT; path=/; domain=.google.com");
+ std::string cookie2(
+ "PREF=ID=14a549990453e42a:TM=1245183232:LM=1245183232:S=Occ7khRVIEE36Ao5;"
+ " path=/; domain=.google.com");
+
+ // No expiry, should be equal to itself after stripping.
+ EXPECT_TRUE(cookie2 == Blacklist::StripCookieExpiry(cookie2));
+
+ // Expiry, should be equal to non-expiry version after stripping.
+ EXPECT_TRUE(cookie2 == Blacklist::StripCookieExpiry(cookie1));
+}
diff --git a/chrome/browser/profile.cc b/chrome/browser/profile.cc
index 67e9810..5c9f977 100644
--- a/chrome/browser/profile.cc
+++ b/chrome/browser/profile.cc
@@ -21,6 +21,7 @@
#include "chrome/browser/history/history.h"
#include "chrome/browser/net/chrome_url_request_context.h"
#include "chrome/browser/password_manager/password_store_default.h"
+#include "chrome/browser/privacy_blacklist/blacklist.h"
#include "chrome/browser/profile_manager.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/search_engines/template_url_fetcher.h"
@@ -273,6 +274,10 @@ class OffTheRecordProfileImpl : public Profile,
return extensions_request_context_;
}
+ virtual Blacklist* GetBlacklist() {
+ return GetOriginalProfile()->GetBlacklist();
+ }
+
virtual SessionService* GetSessionService() {
// Don't save any sessions when off the record.
return NULL;
@@ -414,6 +419,7 @@ ProfileImpl::ProfileImpl(const FilePath& path)
request_context_(NULL),
media_request_context_(NULL),
extensions_request_context_(NULL),
+ blacklist_(NULL),
history_service_created_(false),
created_web_data_service_(false),
created_password_store_(false),
@@ -440,6 +446,18 @@ ProfileImpl::ProfileImpl(const FilePath& path)
personalization_.reset(Personalization::CreateProfilePersonalization(this));
#endif
+ if (CommandLine::ForCurrentProcess()->
+ HasSwitch(switches::kPrivacyBlacklist)) {
+ std::wstring option = CommandLine::ForCurrentProcess()->GetSwitchValue(
+ switches::kPrivacyBlacklist);
+#if defined(OS_POSIX)
+ FilePath path(WideToUTF8(option));
+#else
+ FilePath path(option);
+#endif
+ blacklist_ = new Blacklist(path);
+ }
+
#if defined(OS_LINUX)
// TODO(port): Remove ifdef when the Linux splash page is not needed.
prefs->transient()->SetString(prefs::kHomePage, "about:linux-splash");
@@ -549,6 +567,10 @@ ProfileImpl::~ProfileImpl() {
CleanupRequestContext(media_request_context_);
CleanupRequestContext(extensions_request_context_);
+ // When the request contexts are gone, the blacklist wont be needed anymore.
+ delete blacklist_;
+ blacklist_ = 0;
+
// HistoryService may call into the BookmarkModel, as such we need to
// delete HistoryService before the BookmarkModel. The destructor for
// HistoryService will join with HistoryService's backend thread so that
@@ -749,6 +771,10 @@ URLRequestContext* ProfileImpl::GetRequestContextForExtensions() {
return extensions_request_context_;
}
+Blacklist* ProfileImpl::GetBlacklist() {
+ return blacklist_;
+}
+
HistoryService* ProfileImpl::GetHistoryService(ServiceAccessType sat) {
if (!history_service_created_) {
history_service_created_ = true;
diff --git a/chrome/browser/profile.h b/chrome/browser/profile.h
index c4203db..1501462 100644
--- a/chrome/browser/profile.h
+++ b/chrome/browser/profile.h
@@ -24,6 +24,7 @@
namespace net {
class ForceTLSState;
}
+class Blacklist;
class BookmarkModel;
class BrowserThemeProvider;
class ChromeURLRequestContext;
@@ -210,6 +211,9 @@ class Profile {
// is only used for a separate cookie store currently.
virtual URLRequestContext* GetRequestContextForExtensions() = 0;
+ // Returns the Privacy Blaclist for this profile.
+ virtual Blacklist* GetBlacklist() = 0;
+
// Returns the session service for this profile. This may return NULL. If
// this profile supports a session service (it isn't off the record), and
// the session service hasn't yet been created, this forces creation of
@@ -339,6 +343,7 @@ class ProfileImpl : public Profile,
virtual URLRequestContext* GetRequestContext();
virtual URLRequestContext* GetRequestContextForMedia();
virtual URLRequestContext* GetRequestContextForExtensions();
+ virtual Blacklist* GetBlacklist();
virtual SessionService* GetSessionService();
virtual void ShutdownSessionService();
virtual bool HasSessionService() const;
@@ -416,6 +421,8 @@ class ProfileImpl : public Profile,
ChromeURLRequestContext* extensions_request_context_;
+ Blacklist* blacklist_;
+
scoped_refptr<DownloadManager> download_manager_;
scoped_refptr<HistoryService> history_service_;
scoped_refptr<WebDataService> web_data_service_;
diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.cc b/chrome/browser/renderer_host/resource_dispatcher_host.cc
index 8eb41af..75cccfc 100644
--- a/chrome/browser/renderer_host/resource_dispatcher_host.cc
+++ b/chrome/browser/renderer_host/resource_dispatcher_host.cc
@@ -22,6 +22,7 @@
#include "chrome/browser/download/save_file_manager.h"
#include "chrome/browser/external_protocol_handler.h"
#include "chrome/browser/plugin_service.h"
+#include "chrome/browser/privacy_blacklist/blacklist.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/async_resource_handler.h"
#include "chrome/browser/renderer_host/buffered_resource_handler.h"
@@ -44,6 +45,7 @@
#include "net/base/net_errors.h"
#include "net/base/ssl_cert_request_info.h"
#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_context.h"
#include "webkit/glue/webappcachecontext.h"
// TODO(port): Move these includes to the above section when porting is done.
@@ -301,6 +303,14 @@ void ResourceDispatcherHost::BeginRequest(
return;
}
+ // Note that context can still be NULL here when running unit tests.
+ const Blacklist::Entry* entry = context && context->blacklist() ?
+ context->blacklist()->findMatch(request_data.url) : NULL;
+ if (entry && entry->IsBlocked(request_data.url)) {
+ // TODO(idanan): Send a ResourceResponse to replace the blocked resource.
+ return;
+ }
+
// Ensure the Chrome plugins are loaded, as they may intercept network
// requests. Does nothing if they are already loaded.
// TODO(mpcomplete): This takes 200 ms! Investigate parallelizing this by
@@ -328,10 +338,18 @@ void ResourceDispatcherHost::BeginRequest(
// Construct the request.
URLRequest* request = new URLRequest(request_data.url, this);
+ if (entry && entry->attributes()) {
+ request->SetUserData((void*)&Blacklist::kRequestDataKey,
+ new Blacklist::RequestData(entry));
+ }
request->set_method(request_data.method);
request->set_first_party_for_cookies(request_data.first_party_for_cookies);
- request->set_referrer(request_data.referrer.spec());
+
+ if (!entry || !(entry->attributes() & Blacklist::kDontSendReferrer))
+ request->set_referrer(request_data.referrer.spec());
+
request->SetExtraRequestHeaders(request_data.headers);
+
int load_flags = request_data.load_flags;
// EV certificate verification could be expensive. We don't want to spend
// time performing EV certificate verification on all resources because