Commit e9c41d2e authored by bauerb@chromium.org's avatar bauerb@chromium.org

Add ManagedModeURLFilter.

ManagedModeURLFilter will eventually allow special treatment (e.g. blocking, notifying) for URLs that aren't on a defined whitelist.

BUG=134417


Review URL: https://chromiumcodereview.appspot.com/10824257

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@151993 0039d316-1c4b-4281-b951-d872f2087c98
parent faf87191
...@@ -128,7 +128,7 @@ class ExtensionWebRequestTest : public testing::Test { ...@@ -128,7 +128,7 @@ class ExtensionWebRequestTest : public testing::Test {
enable_referrers_.Init( enable_referrers_.Init(
prefs::kEnableReferrers, profile_.GetTestingPrefService(), NULL); prefs::kEnableReferrers, profile_.GetTestingPrefService(), NULL);
network_delegate_.reset(new ChromeNetworkDelegate( network_delegate_.reset(new ChromeNetworkDelegate(
event_router_.get(), NULL, NULL, &profile_, event_router_.get(), NULL, NULL, NULL, &profile_,
CookieSettings::Factory::GetForProfile(&profile_), &enable_referrers_, CookieSettings::Factory::GetForProfile(&profile_), &enable_referrers_,
NULL)); NULL));
context_.reset(new TestURLRequestContext(true)); context_.reset(new TestURLRequestContext(true));
...@@ -443,7 +443,7 @@ class ExtensionWebRequestHeaderModificationTest : ...@@ -443,7 +443,7 @@ class ExtensionWebRequestHeaderModificationTest :
enable_referrers_.Init( enable_referrers_.Init(
prefs::kEnableReferrers, profile_.GetTestingPrefService(), NULL); prefs::kEnableReferrers, profile_.GetTestingPrefService(), NULL);
network_delegate_.reset(new ChromeNetworkDelegate( network_delegate_.reset(new ChromeNetworkDelegate(
event_router_.get(), NULL, NULL, &profile_, event_router_.get(), NULL, NULL, NULL, &profile_,
CookieSettings::Factory::GetForProfile(&profile_), &enable_referrers_, CookieSettings::Factory::GetForProfile(&profile_), &enable_referrers_,
NULL)); NULL));
context_.reset(new TestURLRequestContext(true)); context_.reset(new TestURLRequestContext(true));
......
...@@ -406,6 +406,7 @@ void IOThread::Init() { ...@@ -406,6 +406,7 @@ void IOThread::Init() {
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL,
&system_enable_referrers_, &system_enable_referrers_,
NULL); NULL);
if (CommandLine::ForCurrentProcess()->HasSwitch( if (CommandLine::ForCurrentProcess()->HasSwitch(
......
...@@ -6,24 +6,61 @@ ...@@ -6,24 +6,61 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_system.h" #include "chrome/browser/extensions/extension_system.h"
#include "chrome/browser/managed_mode_url_filter.h"
#include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h"
#include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/browser_window.h"
#include "chrome/common/chrome_notification_types.h" #include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h" #include "content/public/browser/notification_service.h"
#include "grit/generated_resources.h" #include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
using content::BrowserThread;
// A bridge from ManagedMode (which lives on the UI thread) to
// ManagedModeURLFilter (which lives on the IO thread).
class ManagedMode::URLFilterContext {
public:
URLFilterContext() {}
~URLFilterContext() {}
const ManagedModeURLFilter* url_filter() const {
return &url_filter_;
}
void SetActive(bool in_managed_mode) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
// Because ManagedMode is a singleton, we can pass the pointer to
// |url_filter_| unretained.
BrowserThread::PostTask(BrowserThread::IO,
FROM_HERE,
base::Bind(
&ManagedModeURLFilter::SetActive,
base::Unretained(&url_filter_),
in_managed_mode));
}
void ShutdownOnUIThread() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, this);
}
private:
ManagedModeURLFilter url_filter_;
DISALLOW_COPY_AND_ASSIGN(URLFilterContext);
};
// static // static
ManagedMode* ManagedMode::GetInstance() { ManagedMode* ManagedMode::GetInstance() {
return Singleton<ManagedMode>::get(); return Singleton<ManagedMode, LeakySingletonTraits<ManagedMode> >::get();
} }
// static // static
...@@ -133,6 +170,16 @@ void ManagedMode::LeaveManagedModeImpl() { ...@@ -133,6 +170,16 @@ void ManagedMode::LeaveManagedModeImpl() {
SetInManagedMode(NULL); SetInManagedMode(NULL);
} }
// static
const ManagedModeURLFilter* ManagedMode::GetURLFilter() {
return GetInstance()->GetURLFilterImpl();
}
const ManagedModeURLFilter* ManagedMode::GetURLFilterImpl() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
return url_filter_context_->url_filter();
}
std::string ManagedMode::GetDebugPolicyProviderName() const { std::string ManagedMode::GetDebugPolicyProviderName() const {
// Save the string space in official builds. // Save the string space in official builds.
#ifdef NDEBUG #ifdef NDEBUG
...@@ -188,14 +235,18 @@ void ManagedMode::OnBrowserRemoved(Browser* browser) { ...@@ -188,14 +235,18 @@ void ManagedMode::OnBrowserRemoved(Browser* browser) {
FinalizeEnter(true); FinalizeEnter(true);
} }
ManagedMode::ManagedMode() : managed_profile_(NULL) { ManagedMode::ManagedMode() : managed_profile_(NULL),
url_filter_context_(new URLFilterContext) {
BrowserList::AddObserver(this); BrowserList::AddObserver(this);
} }
ManagedMode::~ManagedMode() { ManagedMode::~ManagedMode() {
// This class usually is a leaky singleton, so this destructor shouldn't be
// called. We still do some cleanup, in case we're owned by a unit test.
BrowserList::RemoveObserver(this); BrowserList::RemoveObserver(this);
DCHECK_EQ(0u, callbacks_.size()); DCHECK_EQ(0u, callbacks_.size());
DCHECK_EQ(0u, browsers_to_close_.size()); DCHECK_EQ(0u, browsers_to_close_.size());
url_filter_context_.release()->ShutdownOnUIThread();
} }
void ManagedMode::Observe(int type, void ManagedMode::Observe(int type,
...@@ -216,10 +267,14 @@ void ManagedMode::Observe(int type, ...@@ -216,10 +267,14 @@ void ManagedMode::Observe(int type,
FinalizeEnter(false); FinalizeEnter(false);
return; return;
} }
default: { case chrome::NOTIFICATION_EXTENSION_LOADED:
NOTREACHED(); case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
if (managed_profile_)
UpdateWhitelist();
break; break;
} }
default:
NOTREACHED();
} }
} }
...@@ -249,17 +304,30 @@ void ManagedMode::SetInManagedMode(Profile* newly_managed_profile) { ...@@ -249,17 +304,30 @@ void ManagedMode::SetInManagedMode(Profile* newly_managed_profile) {
// Register the ManagementPolicy::Provider before changing the pref when // Register the ManagementPolicy::Provider before changing the pref when
// setting it, and unregister it after changing the pref when clearing it, // setting it, and unregister it after changing the pref when clearing it,
// so pref observers see the correct ManagedMode state. // so pref observers see the correct ManagedMode state.
if (newly_managed_profile) { bool in_managed_mode = !!newly_managed_profile;
if (in_managed_mode) {
DCHECK(!managed_profile_ || managed_profile_ == newly_managed_profile); DCHECK(!managed_profile_ || managed_profile_ == newly_managed_profile);
extensions::ExtensionSystem::Get( extensions::ExtensionSystem::Get(
newly_managed_profile)->management_policy()->RegisterProvider(this); newly_managed_profile)->management_policy()->RegisterProvider(this);
g_browser_process->local_state()->SetBoolean(prefs::kInManagedMode, true); registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
content::Source<Profile>(newly_managed_profile));
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
content::Source<Profile>(newly_managed_profile));
} else { } else {
extensions::ExtensionSystem::Get( extensions::ExtensionSystem::Get(
managed_profile_)->management_policy()->UnregisterProvider(this); managed_profile_)->management_policy()->UnregisterProvider(this);
g_browser_process->local_state()->SetBoolean(prefs::kInManagedMode, false); registrar_.Remove(this, chrome::NOTIFICATION_EXTENSION_LOADED,
content::Source<Profile>(managed_profile_));
registrar_.Remove(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
content::Source<Profile>(managed_profile_));
} }
managed_profile_ = newly_managed_profile; managed_profile_ = newly_managed_profile;
url_filter_context_->SetActive(in_managed_mode);
g_browser_process->local_state()->SetBoolean(prefs::kInManagedMode,
in_managed_mode);
if (in_managed_mode)
UpdateWhitelist();
// This causes the avatar and the profile menu to get updated. // This causes the avatar and the profile menu to get updated.
content::NotificationService::current()->Notify( content::NotificationService::current()->Notify(
...@@ -267,3 +335,8 @@ void ManagedMode::SetInManagedMode(Profile* newly_managed_profile) { ...@@ -267,3 +335,8 @@ void ManagedMode::SetInManagedMode(Profile* newly_managed_profile) {
content::NotificationService::AllBrowserContextsAndSources(), content::NotificationService::AllBrowserContextsAndSources(),
content::NotificationService::NoDetails()); content::NotificationService::NoDetails());
} }
void ManagedMode::UpdateWhitelist() {
DCHECK(managed_profile_);
// TODO(bauerb): Update URL filter with whitelist.
}
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/singleton.h" #include "base/memory/singleton.h"
#include "chrome/browser/extensions/management_policy.h" #include "chrome/browser/extensions/management_policy.h"
#include "chrome/browser/ui/browser_list_observer.h" #include "chrome/browser/ui/browser_list_observer.h"
...@@ -20,6 +21,7 @@ ...@@ -20,6 +21,7 @@
class Browser; class Browser;
template<typename T> template<typename T>
struct DefaultSingletonTraits; struct DefaultSingletonTraits;
class ManagedModeURLFilter;
class PrefService; class PrefService;
class Profile; class Profile;
...@@ -27,6 +29,7 @@ class Profile; ...@@ -27,6 +29,7 @@ class Profile;
// person by pre-configuring and then locking a managed User profile. // person by pre-configuring and then locking a managed User profile.
// The ManagedMode class provides methods to check whether the browser is in // The ManagedMode class provides methods to check whether the browser is in
// managed mode, and to attempt to enter or leave managed mode. // managed mode, and to attempt to enter or leave managed mode.
// Except where otherwise noted, this class should be used on the UI thread.
class ManagedMode : public chrome::BrowserListObserver, class ManagedMode : public chrome::BrowserListObserver,
public extensions::ManagementPolicy::Provider, public extensions::ManagementPolicy::Provider,
public content::NotificationObserver { public content::NotificationObserver {
...@@ -45,6 +48,9 @@ class ManagedMode : public chrome::BrowserListObserver, ...@@ -45,6 +48,9 @@ class ManagedMode : public chrome::BrowserListObserver,
static void EnterManagedMode(Profile* profile, const EnterCallback& callback); static void EnterManagedMode(Profile* profile, const EnterCallback& callback);
static void LeaveManagedMode(); static void LeaveManagedMode();
// Returns the URL filter. This method should only be called on the IO thread.
static const ManagedModeURLFilter* GetURLFilter();
// ExtensionManagementPolicy::Provider implementation: // ExtensionManagementPolicy::Provider implementation:
virtual std::string GetDebugPolicyProviderName() const OVERRIDE; virtual std::string GetDebugPolicyProviderName() const OVERRIDE;
virtual bool UserMayLoad(const extensions::Extension* extension, virtual bool UserMayLoad(const extensions::Extension* extension,
...@@ -70,8 +76,10 @@ class ManagedMode : public chrome::BrowserListObserver, ...@@ -70,8 +76,10 @@ class ManagedMode : public chrome::BrowserListObserver,
Profile* managed_profile_; Profile* managed_profile_;
private: private:
class URLFilterContext;
friend class Singleton<ManagedMode, LeakySingletonTraits<ManagedMode> >;
friend struct DefaultSingletonTraits<ManagedMode>; friend struct DefaultSingletonTraits<ManagedMode>;
friend class Singleton<ManagedMode>;
FRIEND_TEST_ALL_PREFIXES(ExtensionApiTest, ManagedModeOnChange); FRIEND_TEST_ALL_PREFIXES(ExtensionApiTest, ManagedModeOnChange);
FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest, FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest,
ManagedModeProhibitsModification); ManagedModeProhibitsModification);
...@@ -87,6 +95,8 @@ class ManagedMode : public chrome::BrowserListObserver, ...@@ -87,6 +95,8 @@ class ManagedMode : public chrome::BrowserListObserver,
void LeaveManagedModeImpl(); void LeaveManagedModeImpl();
const ManagedModeURLFilter* GetURLFilterImpl();
void FinalizeEnter(bool result); void FinalizeEnter(bool result);
// Platform-specific methods that confirm whether we can enter or leave // Platform-specific methods that confirm whether we can enter or leave
...@@ -103,8 +113,12 @@ class ManagedMode : public chrome::BrowserListObserver, ...@@ -103,8 +113,12 @@ class ManagedMode : public chrome::BrowserListObserver,
// testing). // testing).
virtual void SetInManagedMode(Profile* newly_managed_profile); virtual void SetInManagedMode(Profile* newly_managed_profile);
void UpdateWhitelist();
content::NotificationRegistrar registrar_; content::NotificationRegistrar registrar_;
scoped_ptr<URLFilterContext> url_filter_context_;
std::set<Browser*> browsers_to_close_; std::set<Browser*> browsers_to_close_;
std::vector<EnterCallback> callbacks_; std::vector<EnterCallback> callbacks_;
......
// Copyright (c) 2012 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/managed_mode_url_filter.h"
#include "base/file_path.h"
#include "base/json/json_file_value_serializer.h"
#include "base/task_runner_util.h"
#include "base/threading/sequenced_worker_pool.h"
#include "chrome/browser/policy/url_blacklist_manager.h"
#include "chrome/common/extensions/matcher/url_matcher.h"
#include "content/public/browser/browser_thread.h"
#include "googleurl/src/gurl.h"
using content::BrowserThread;
using extensions::URLMatcher;
using extensions::URLMatcherConditionSet;
namespace {
scoped_ptr<URLMatcher> CreateWhitelistOnBlockingPoolThread(
const std::vector<std::string>& patterns) {
DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
scoped_ptr<URLMatcher> url_matcher(new URLMatcher());
URLMatcherConditionSet::Vector all_conditions;
URLMatcherConditionSet::ID id = 0;
for (std::vector<std::string>::const_iterator it = patterns.begin();
it != patterns.end(); ++it) {
std::string scheme;
std::string host;
uint16 port;
std::string path;
bool match_subdomains = true;
if (!policy::URLBlacklist::FilterToComponents(
*it, &scheme, &host, &match_subdomains, &port, &path)) {
LOG(ERROR) << "Invalid pattern " << *it;
continue;
}
scoped_refptr<extensions::URLMatcherConditionSet> condition_set =
policy::URLBlacklist::CreateConditionSet(
url_matcher.get(), ++id,
scheme, host, match_subdomains, port, path);
all_conditions.push_back(condition_set);
}
url_matcher->AddConditionSets(all_conditions);
return url_matcher.Pass();
}
} // namespace
ManagedModeURLFilter::ManagedModeURLFilter()
: ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)),
active_(false),
url_matcher_(new URLMatcher()) {
// Detach from the current thread so we can be constructed on a different
// thread than the one where we're used.
DetachFromThread();
}
ManagedModeURLFilter::~ManagedModeURLFilter() {
DCHECK(CalledOnValidThread());
}
bool ManagedModeURLFilter::IsURLWhitelisted(const GURL& url) const {
DCHECK(CalledOnValidThread());
if (!active_)
return true;
if (!policy::URLBlacklist::HasStandardScheme(url))
return true;
std::set<URLMatcherConditionSet::ID> matching_ids =
url_matcher_->MatchURL(url);
return !matching_ids.empty();
}
void ManagedModeURLFilter::SetActive(bool active) {
DCHECK(CalledOnValidThread());
active_ = active;
}
void ManagedModeURLFilter::SetWhitelist(
const std::vector<std::string>& patterns,
const base::Closure& continuation) {
DCHECK(CalledOnValidThread());
base::PostTaskAndReplyWithResult(
BrowserThread::GetBlockingPool(),
FROM_HERE,
base::Bind(&CreateWhitelistOnBlockingPoolThread, patterns),
base::Bind(&ManagedModeURLFilter::SetURLMatcher,
weak_ptr_factory_.GetWeakPtr(), continuation));
}
void ManagedModeURLFilter::SetURLMatcher(const base::Closure& continuation,
scoped_ptr<URLMatcher> url_matcher) {
DCHECK(CalledOnValidThread());
url_matcher_ = url_matcher.Pass();
continuation.Run();
}
// Copyright (c) 2012 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_MANAGED_MODE_URL_FILTER_H_
#define CHROME_BROWSER_MANAGED_MODE_URL_FILTER_H_
#include "base/callback_forward.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/non_thread_safe.h"
#include "base/values.h"
class FilePath;
class GURL;
namespace extensions {
class URLMatcher;
}
class ManagedModeURLFilter : public base::NonThreadSafe {
public:
ManagedModeURLFilter();
~ManagedModeURLFilter();
// Returns true if the URL is matched by the filter.
bool IsURLWhitelisted(const GURL& url) const;
// Sets whether the filter is active or not (default is inactive).
// If the filter is inactive, the whitelist will match any URL.
void SetActive(bool in_managed_mode);
// Sets the whitelist from the passed in list of |patterns|.
void SetWhitelist(const std::vector<std::string>& patterns,
const base::Closure& continuation);
private:
void SetURLMatcher(const base::Closure& callback,
scoped_ptr<extensions::URLMatcher> url_matcher);
base::WeakPtrFactory<ManagedModeURLFilter> weak_ptr_factory_;
bool active_;
scoped_ptr<extensions::URLMatcher> url_matcher_;
DISALLOW_COPY_AND_ASSIGN(ManagedModeURLFilter);
};
#endif // CHROME_BROWSER_MANAGED_MODE_URL_FILTER_H_
// Copyright (c) 2012 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 "base/bind.h"
#include "base/bind_helpers.h"
#include "base/message_loop.h"
#include "base/run_loop.h"
#include "chrome/browser/managed_mode_url_filter.h"
#include "googleurl/src/gurl.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
class FailClosureHelper : public base::RefCountedThreadSafe<FailClosureHelper> {
public:
explicit FailClosureHelper(const base::Closure& cb) : closure_runner_(cb) {}
void Fail() {
FAIL();
}
private:
friend class base::RefCountedThreadSafe<FailClosureHelper>;
virtual ~FailClosureHelper() {}
base::ScopedClosureRunner closure_runner_;
};
// Returns a closure that FAILs when it is called. As soon as the closure is
// destroyed (because the last reference to it is dropped), |continuation| is
// called.
base::Closure FailClosure(const base::Closure& continuation) {
scoped_refptr<FailClosureHelper> helper = new FailClosureHelper(continuation);
return base::Bind(&FailClosureHelper::Fail, helper);
}
} // namespace
class ManagedModeURLFilterTest : public ::testing::Test {
public:
ManagedModeURLFilterTest() {}
virtual ~ManagedModeURLFilterTest() {}
virtual void SetUp() OVERRIDE {
filter_.reset(new ManagedModeURLFilter);
filter_->SetActive(true);
}
protected:
MessageLoop message_loop_;
base::RunLoop run_loop_;
scoped_ptr<ManagedModeURLFilter> filter_;
};
TEST_F(ManagedModeURLFilterTest, Basic) {
std::vector<std::string> list;
// Allow domain and all subdomains, for any filtered scheme.
list.push_back("google.com");
filter_->SetWhitelist(list, run_loop_.QuitClosure());
run_loop_.Run();
EXPECT_TRUE(filter_->IsURLWhitelisted(GURL("http://google.com")));
EXPECT_TRUE(filter_->IsURLWhitelisted(GURL("http://google.com/")));
EXPECT_TRUE(filter_->IsURLWhitelisted(GURL("http://google.com/whatever")));
EXPECT_TRUE(filter_->IsURLWhitelisted(GURL("https://google.com/")));
EXPECT_FALSE(filter_->IsURLWhitelisted(GURL("http://notgoogle.com/")));
EXPECT_TRUE(filter_->IsURLWhitelisted(GURL("http://mail.google.com")));
EXPECT_TRUE(filter_->IsURLWhitelisted(GURL("http://x.mail.google.com")));
EXPECT_TRUE(filter_->IsURLWhitelisted(GURL("https://x.mail.google.com/")));
EXPECT_TRUE(filter_->IsURLWhitelisted(GURL("http://x.y.google.com/a/b")));
EXPECT_FALSE(filter_->IsURLWhitelisted(GURL("http://youtube.com/")));
EXPECT_TRUE(filter_->IsURLWhitelisted(GURL("bogus://youtube.com/")));
EXPECT_TRUE(filter_->IsURLWhitelisted(GURL("chrome://youtube.com/")));
}
TEST_F(ManagedModeURLFilterTest, Inactive) {
filter_->SetActive(false);
std::vector<std::string> list;
list.push_back("google.com");
filter_->SetWhitelist(list, run_loop_.QuitClosure());
run_loop_.Run();
// If the filter is inactive, every URL should be whitelisted.
EXPECT_TRUE(filter_->IsURLWhitelisted(GURL("http://google.com")));
EXPECT_TRUE(filter_->IsURLWhitelisted(GURL("https://www.example.com")));
}
TEST_F(ManagedModeURLFilterTest, Shutdown) {
std::vector<std::string> list;
list.push_back("google.com");
filter_->SetWhitelist(list, FailClosure(run_loop_.QuitClosure()));
// Destroy the filter before we set the URLMatcher.
filter_.reset();
run_loop_.Run();
}
TEST_F(ManagedModeURLFilterTest, Scheme) {
std::vector<std::string> list;
// Filter only http, ftp and ws schemes.
list.push_back("http://secure.com");
list.push_back("ftp://secure.com");
list.push_back("ws://secure.com");
filter_->SetWhitelist(list, run_loop_.QuitClosure());
run_loop_.Run();
EXPECT_TRUE(filter_->IsURLWhitelisted(GURL("http://secure.com")));
EXPECT_TRUE(filter_->IsURLWhitelisted(GURL("http://secure.com/whatever")));
EXPECT_TRUE(filter_->IsURLWhitelisted(GURL("ftp://secure.com/")));
EXPECT_TRUE(filter_->IsURLWhitelisted(GURL("ws://secure.com")));
EXPECT_FALSE(filter_->IsURLWhitelisted(GURL("https://secure.com/")));
EXPECT_FALSE(filter_->IsURLWhitelisted(GURL("wss://secure.com")));
EXPECT_TRUE(filter_->IsURLWhitelisted(GURL("http://www.secure.com")));
EXPECT_FALSE(filter_->IsURLWhitelisted(GURL("https://www.secure.com")));
EXPECT_FALSE(filter_->IsURLWhitelisted(GURL("wss://www.secure.com")));
}
TEST_F(ManagedModeURLFilterTest, Path) {
std::vector<std::string> list;
// Filter only a certain path prefix.
list.push_back("path.to/ruin");
filter_->SetWhitelist(list, run_loop_.QuitClosure());
run_loop_.Run();
EXPECT_TRUE(filter_->IsURLWhitelisted(GURL("http://path.to/ruin")));
EXPECT_TRUE(filter_->IsURLWhitelisted(GURL("https://path.to/ruin")));
EXPECT_TRUE(filter_->IsURLWhitelisted(GURL("http://path.to/ruins")));
EXPECT_TRUE(filter_->IsURLWhitelisted(GURL("http://path.to/ruin/signup")));
EXPECT_TRUE(filter_->IsURLWhitelisted(GURL("http://www.path.to/ruin")));
EXPECT_FALSE(filter_->IsURLWhitelisted(GURL("http://path.to/fortune")));
}
TEST_F(ManagedModeURLFilterTest, PathAndScheme) {
std::vector<std::string> list;
// Filter only a certain path prefix and scheme.
list.push_back("https://s.aaa.com/path");
filter_->SetWhitelist(list, run_loop_.QuitClosure());
run_loop_.Run();
EXPECT_TRUE(filter_->IsURLWhitelisted(GURL("https://s.aaa.com/path")));
EXPECT_TRUE(filter_->IsURLWhitelisted(GURL("https://s.aaa.com/path/bbb")));
EXPECT_FALSE(filter_->IsURLWhitelisted(GURL("http://s.aaa.com/path")));
EXPECT_FALSE(filter_->IsURLWhitelisted(GURL("https://aaa.com/path")));
EXPECT_FALSE(filter_->IsURLWhitelisted(GURL("https://x.aaa.com/path")));
EXPECT_FALSE(filter_->IsURLWhitelisted(GURL("https://s.aaa.com/bbb")));
EXPECT_FALSE(filter_->IsURLWhitelisted(GURL("https://s.aaa.com/")));
}
TEST_F(ManagedModeURLFilterTest, Host) {
std::vector<std::string> list;
// Filter only a certain hostname, without subdomains.
list.push_back(".www.example.com");
filter_->SetWhitelist(list, run_loop_.QuitClosure());
run_loop_.Run();
EXPECT_TRUE(filter_->IsURLWhitelisted(GURL("http://www.example.com")));
EXPECT_FALSE(filter_->IsURLWhitelisted(GURL("http://example.com")));
EXPECT_FALSE(filter_->IsURLWhitelisted(GURL("http://subdomain.example.com")));
}
TEST_F(ManagedModeURLFilterTest, IPAddress) {
std::vector<std::string> list;
// Filter an ip address.
list.push_back("123.123.123.123");
filter_->SetWhitelist(list, run_loop_.QuitClosure());
run_loop_.Run();
EXPECT_TRUE(filter_->IsURLWhitelisted(GURL("http://123.123.123.123/")));
EXPECT_FALSE(filter_->IsURLWhitelisted(GURL("http://123.123.123.124/")));
}
...@@ -33,6 +33,10 @@ ...@@ -33,6 +33,10 @@
#include "net/socket_stream/socket_stream.h" #include "net/socket_stream/socket_stream.h"
#include "net/url_request/url_request.h" #include "net/url_request/url_request.h"
#if !defined(OS_ANDROID)
#include "chrome/browser/managed_mode_url_filter.h"
#endif
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
#include "base/chromeos/chromeos_version.h" #include "base/chromeos/chromeos_version.h"
#endif #endif
...@@ -129,6 +133,7 @@ ChromeNetworkDelegate::ChromeNetworkDelegate( ...@@ -129,6 +133,7 @@ ChromeNetworkDelegate::ChromeNetworkDelegate(
extensions::EventRouterForwarder* event_router, extensions::EventRouterForwarder* event_router,
ExtensionInfoMap* extension_info_map, ExtensionInfoMap* extension_info_map,
const policy::URLBlacklistManager* url_blacklist_manager, const policy::URLBlacklistManager* url_blacklist_manager,
const ManagedModeURLFilter* managed_mode_url_filter,
void* profile, void* profile,
CookieSettings* cookie_settings, CookieSettings* cookie_settings,
BooleanPrefMember* enable_referrers, BooleanPrefMember* enable_referrers,
...@@ -139,6 +144,7 @@ ChromeNetworkDelegate::ChromeNetworkDelegate( ...@@ -139,6 +144,7 @@ ChromeNetworkDelegate::ChromeNetworkDelegate(
extension_info_map_(extension_info_map), extension_info_map_(extension_info_map),
enable_referrers_(enable_referrers), enable_referrers_(enable_referrers),
url_blacklist_manager_(url_blacklist_manager), url_blacklist_manager_(url_blacklist_manager),
managed_mode_url_filter_(managed_mode_url_filter),
cache_stats_(cache_stats) { cache_stats_(cache_stats) {
DCHECK(event_router); DCHECK(event_router);
DCHECK(enable_referrers); DCHECK(enable_referrers);
...@@ -185,6 +191,14 @@ int ChromeNetworkDelegate::OnBeforeURLRequest( ...@@ -185,6 +191,14 @@ int ChromeNetworkDelegate::OnBeforeURLRequest(
} }
#endif #endif
#if !defined(OS_ANDROID)
if (managed_mode_url_filter_ &&
!managed_mode_url_filter_->IsURLWhitelisted(request->url())) {
// Block for now.
return net::ERR_NETWORK_ACCESS_DENIED;
}
#endif
ForwardRequestStatus(REQUEST_STARTED, request, profile_); ForwardRequestStatus(REQUEST_STARTED, request, profile_);
if (!enable_referrers_->GetValue()) if (!enable_referrers_->GetValue())
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
class CookieSettings; class CookieSettings;
class ExtensionInfoMap; class ExtensionInfoMap;
class ManagedModeURLFilter;
class PrefService; class PrefService;
template<class T> class PrefMember; template<class T> class PrefMember;
...@@ -43,6 +44,7 @@ class ChromeNetworkDelegate : public net::NetworkDelegate { ...@@ -43,6 +44,7 @@ class ChromeNetworkDelegate : public net::NetworkDelegate {
extensions::EventRouterForwarder* event_router, extensions::EventRouterForwarder* event_router,
ExtensionInfoMap* extension_info_map, ExtensionInfoMap* extension_info_map,
const policy::URLBlacklistManager* url_blacklist_manager, const policy::URLBlacklistManager* url_blacklist_manager,
const ManagedModeURLFilter* managed_mode_url_filter,
void* profile, void* profile,
CookieSettings* cookie_settings, CookieSettings* cookie_settings,
BooleanPrefMember* enable_referrers, BooleanPrefMember* enable_referrers,
...@@ -121,6 +123,10 @@ class ChromeNetworkDelegate : public net::NetworkDelegate { ...@@ -121,6 +123,10 @@ class ChromeNetworkDelegate : public net::NetworkDelegate {
// Weak, owned by our owner. // Weak, owned by our owner.
const policy::URLBlacklistManager* url_blacklist_manager_; const policy::URLBlacklistManager* url_blacklist_manager_;
// Weak pointer. The owner of this object needs to make sure that the
// |managed_mode_url_filter_| outlives it.
const ManagedModeURLFilter* managed_mode_url_filter_;
// When true, allow access to all file:// URLs. // When true, allow access to all file:// URLs.
static bool g_allow_file_access_; static bool g_allow_file_access_;
......
...@@ -31,7 +31,7 @@ class ChromeNetworkDelegateTest : public testing::Test { ...@@ -31,7 +31,7 @@ class ChromeNetworkDelegateTest : public testing::Test {
scoped_ptr<ChromeNetworkDelegate> CreateNetworkDelegate() { scoped_ptr<ChromeNetworkDelegate> CreateNetworkDelegate() {
return scoped_ptr<ChromeNetworkDelegate>(new ChromeNetworkDelegate( return scoped_ptr<ChromeNetworkDelegate>(new ChromeNetworkDelegate(
forwarder_.get(), NULL, NULL, NULL, NULL, &pref_member_, NULL)); forwarder_.get(), NULL, NULL, NULL, NULL, NULL, &pref_member_, NULL));
} }
// Implementation moved here for access to private bits. // Implementation moved here for access to private bits.
......
...@@ -64,6 +64,10 @@ ...@@ -64,6 +64,10 @@
#include "net/url_request/data_protocol_handler.h" #include "net/url_request/data_protocol_handler.h"
#include "net/url_request/url_request.h" #include "net/url_request/url_request.h"
#if !defined(OS_ANDROID)
#include "chrome/browser/managed_mode.h"
#endif
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/gdata/gdata_protocol_handler.h" #include "chrome/browser/chromeos/gdata/gdata_protocol_handler.h"
#include "chrome/browser/chromeos/gview_request_interceptor.h" #include "chrome/browser/chromeos/gview_request_interceptor.h"
...@@ -479,6 +483,11 @@ void ProfileIOData::LazyInitialize() const { ...@@ -479,6 +483,11 @@ void ProfileIOData::LazyInitialize() const {
io_thread_globals->extension_event_router_forwarder.get(), io_thread_globals->extension_event_router_forwarder.get(),
profile_params_->extension_info_map, profile_params_->extension_info_map,
url_blacklist_manager_.get(), url_blacklist_manager_.get(),
#if !defined(OS_ANDROID)
ManagedMode::GetURLFilter(),
#else
NULL,
#endif
profile_params_->profile, profile_params_->profile,
profile_params_->cookie_settings, profile_params_->cookie_settings,
&enable_referrers_, &enable_referrers_,
......
...@@ -1427,6 +1427,8 @@ ...@@ -1427,6 +1427,8 @@
'browser/mac/security_wrappers.h', 'browser/mac/security_wrappers.h',
'browser/managed_mode.cc', 'browser/managed_mode.cc',
'browser/managed_mode.h', 'browser/managed_mode.h',
'browser/managed_mode_url_filter.cc',
'browser/managed_mode_url_filter.h',
'browser/media/media_internals.cc', 'browser/media/media_internals.cc',
'browser/media/media_internals.h', 'browser/media/media_internals.h',
'browser/media/media_stream_capture_indicator.cc', 'browser/media/media_stream_capture_indicator.cc',
...@@ -4994,6 +4996,8 @@ ...@@ -4994,6 +4996,8 @@
'browser/lifetime/application_lifetime_stub.cc', 'browser/lifetime/application_lifetime_stub.cc',
'browser/managed_mode.cc', 'browser/managed_mode.cc',
'browser/managed_mode.h', 'browser/managed_mode.h',
'browser/managed_mode_url_filter.cc',
'browser/managed_mode_url_filter.h',
'browser/net/gaia/gaia_oauth_fetcher.cc', 'browser/net/gaia/gaia_oauth_fetcher.cc',
'browser/page_cycler/page_cycler.cc', 'browser/page_cycler/page_cycler.cc',
'browser/page_cycler/page_cycler.h', 'browser/page_cycler/page_cycler.h',
......
...@@ -1357,6 +1357,7 @@ ...@@ -1357,6 +1357,7 @@
'browser/language_usage_metrics_unittest.cc', 'browser/language_usage_metrics_unittest.cc',
'browser/mac/keystone_glue_unittest.mm', 'browser/mac/keystone_glue_unittest.mm',
'browser/managed_mode_unittest.cc', 'browser/managed_mode_unittest.cc',
'browser/managed_mode_url_filter_unittest.cc',
'browser/media/media_internals_unittest.cc', 'browser/media/media_internals_unittest.cc',
'browser/media_gallery/media_device_notifications_chromeos_unittest.cc', 'browser/media_gallery/media_device_notifications_chromeos_unittest.cc',
'browser/media_gallery/media_device_notifications_linux_unittest.cc', 'browser/media_gallery/media_device_notifications_linux_unittest.cc',
...@@ -2441,6 +2442,7 @@ ...@@ -2441,6 +2442,7 @@
'browser/browser_commands_unittest.cc', 'browser/browser_commands_unittest.cc',
'browser/extensions/extension_ui_unittest.cc', 'browser/extensions/extension_ui_unittest.cc',
'browser/managed_mode_unittest.cc', 'browser/managed_mode_unittest.cc',
'browser/managed_mode_url_filter_unittest.cc',
'browser/net/gaia/gaia_oauth_fetcher_unittest.cc', 'browser/net/gaia/gaia_oauth_fetcher_unittest.cc',
'browser/page_cycler/page_cycler_unittest.cc', 'browser/page_cycler/page_cycler_unittest.cc',
'browser/profiles/off_the_record_profile_impl_unittest.cc', 'browser/profiles/off_the_record_profile_impl_unittest.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment