15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_BROWSER_POLICY_URL_BLACKLIST_MANAGER_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_POLICY_URL_BLACKLIST_MANAGER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback_forward.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/containers/hash_tables.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_change_registrar.h"
18d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)#include "components/url_matcher/url_matcher.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GURL;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PrefService;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ListValue;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace net {
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class URLRequest;
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace user_prefs {
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class PrefRegistrySyncable;
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace policy {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Contains a set of filters to block and allow certain URLs, and matches GURLs
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// against this set. The filters are currently kept in memory.
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class URLBlacklist {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLBlacklist();
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~URLBlacklist();
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allows or blocks URLs matching one of the filters, depending on |allow|.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddFilters(bool allow, const base::ListValue* filters);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // URLs matching one of the |filters| will be blocked. The filter format is
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // documented at
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // http://www.chromium.org/administrators/url-blacklist-filter-format.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Block(const base::ListValue* filters);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // URLs matching one of the |filters| will be allowed. If a URL is both
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Blocked and Allowed, Allow takes precedence.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Allow(const base::ListValue* filters);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the URL is blocked.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsURLBlocked(const GURL& url) const;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns the number of items in the list.
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t Size() const;
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Splits a URL filter into its components. A GURL isn't used because these
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // can be invalid URLs e.g. "google.com".
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns false if the URL couldn't be parsed.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The |host| is preprocessed so it can be passed to URLMatcher for the
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // appropriate condition.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The optional username and password are ignored.
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |match_subdomains| specifies whether the filter should include subdomains
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of the hostname (if it is one.)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |port| is 0 if none is explicitly defined.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |path| does not include query parameters.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool FilterToComponents(const std::string& filter,
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 std::string* scheme,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 std::string* host,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 bool* match_subdomains,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 uint16* port,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 std::string* path);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a condition set that can be used with the |url_matcher|. |id| needs
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to be a unique number that will be returned by the |url_matcher| if the URL
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // matches that condition set.
82d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  static scoped_refptr<url_matcher::URLMatcherConditionSet> CreateConditionSet(
83d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      url_matcher::URLMatcher* url_matcher,
84d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      url_matcher::URLMatcherConditionSet::ID id,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& scheme,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& host,
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool match_subdomains,
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      uint16 port,
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& path);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct FilterComponents;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if |lhs| takes precedence over |rhs|.
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool FilterTakesPrecedence(const FilterComponents& lhs,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const FilterComponents& rhs);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  url_matcher::URLMatcherConditionSet::ID id_;
99d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  std::map<url_matcher::URLMatcherConditionSet::ID, FilterComponents> filters_;
100d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  scoped_ptr<url_matcher::URLMatcher> url_matcher_;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(URLBlacklist);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tracks the blacklist policies for a given profile, and updates it on changes.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class interacts with both the UI thread, where notifications of pref
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// changes are received from, and the IO thread, which owns it (in the
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ProfileIOData) and checks for blacklisted URLs (from ChromeNetworkDelegate).
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It must be constructed on the UI thread, to set up |ui_weak_ptr_factory_| and
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the prefs listeners.
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ShutdownOnUIThread must be called from UI before destruction, to release
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the prefs listeners on the UI thread. This is done from ProfileIOData.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Update tasks from the UI thread can post safely to the IO thread, since the
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destruction order of Profile and ProfileIOData guarantees that if this
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// exists in UI, then a potential destruction on IO will come after any task
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// posted to IO from that method on UI. This is used to go through IO before
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the actual update starts, and grab a WeakPtr.
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class URLBlacklistManager {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Must be constructed on the UI thread.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit URLBlacklistManager(PrefService* pref_service);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~URLBlacklistManager();
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Must be called on the UI thread, before destruction.
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ShutdownOnUIThread();
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if |url| is blocked by the current blacklist. Must be called
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from the IO thread.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsURLBlocked(const GURL& url) const;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns true if |request| is blocked by the current blacklist.
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Only main frame and sub frame requests may be blocked; other sub resources
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // or background downloads (e.g. extensions updates, sync, etc) are not
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // filtered. The sync signin page is also not filtered.
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Must be called from the IO thread.
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool IsRequestBlocked(const net::URLRequest& request) const;
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Replaces the current blacklist. Must be called on the IO thread.
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Virtual for testing.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetBlacklist(scoped_ptr<URLBlacklist> blacklist);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Registers the preferences related to blacklisting in the given PrefService.
1477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used to delay updating the blacklist while the preferences are
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // changing, and execute only one update per simultaneous prefs changes.
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ScheduleUpdate();
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Updates the blacklist using the current preference values.
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Virtual for testing.
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Update();
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Starts the blacklist update on the IO thread, using the filters in
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |block| and |allow|. Protected for testing.
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UpdateOnIO(scoped_ptr<base::ListValue> block,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  scoped_ptr<base::ListValue> allow);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ---------
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // UI thread
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ---------
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used to post update tasks to the UI thread.
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<URLBlacklistManager> ui_weak_ptr_factory_;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used to track the policies and update the blacklist on changes.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrefChangeRegistrar pref_change_registrar_;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrefService* pref_service_;  // Weak.
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ---------
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // IO thread
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ---------
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used to get |weak_ptr_| to self on the IO thread.
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<URLBlacklistManager> io_weak_ptr_factory_;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The current blacklist.
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<URLBlacklist> blacklist_;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(URLBlacklistManager);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace policy
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_BROWSER_POLICY_URL_BLACKLIST_MANAGER_H_
191