15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 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) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/policy/core/browser/url_blacklist_manager.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/files/file_path.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/location.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/sequenced_task_runner.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/task_runner_util.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/policy/core/common/policy_pref_names.h" 18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/pref_registry/pref_registry_syncable.h" 19c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "net/base/filename_util.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/load_flags.h" 21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "net/base/net_errors.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/url_request.h" 2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "url/url_constants.h" 24a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "url/url_parse.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using url_matcher::URLMatcher; 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using url_matcher::URLMatcherCondition; 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using url_matcher::URLMatcherConditionFactory; 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using url_matcher::URLMatcherConditionSet; 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using url_matcher::URLMatcherPortFilter; 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using url_matcher::URLMatcherSchemeFilter; 32a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochusing url_matcher::URLQueryElementMatcherCondition; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace policy { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// List of schemes of URLs that should not be blocked by the "*" wildcard in 3903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// the blacklist. Note that URLs with these schemes can still be blocked with 4003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// a more specific filter e.g. "chrome-extension://*". 4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// The schemes are hardcoded here to avoid dependencies on //extensions and 4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// //chrome. 4303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const char* kBypassBlacklistWildcardForSchemes[] = { 4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // For internal extension URLs e.g. the Bookmark Manager and the File 4503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Manager on Chrome OS. 4603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "chrome-extension", 4703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 4803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // NTP on Android. 4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "chrome-native", 5003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 5103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // NTP on other platforms. 5203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "chrome-search", 5303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}; 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Maximum filters per policy. Filters over this index are ignored. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const size_t kMaxFiltersPerPolicy = 1000; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// A task that builds the blacklist on a background thread. 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)scoped_ptr<URLBlacklist> BuildBlacklist( 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::ListValue> block, 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::ListValue> allow, 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) URLBlacklist::SegmentURLCallback segment_url) { 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<URLBlacklist> blacklist(new URLBlacklist(segment_url)); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blacklist->Block(block.get()); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blacklist->Allow(allow.get()); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return blacklist.Pass(); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 69a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Tokenise the parameter |query| and add appropriate query element matcher 70a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// conditions to the |query_conditions|. 71a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid ProcessQueryToConditions( 72a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch url_matcher::URLMatcherConditionFactory* condition_factory, 73a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const std::string& query, 74a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch bool allow, 75a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch std::set<URLQueryElementMatcherCondition>* query_conditions) { 76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) url::Component query_left = url::MakeRange(0, query.length()); 77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) url::Component key; 78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) url::Component value; 79a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Depending on the filter type being black-list or white-list, the matcher 80a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // choose any or every match. The idea is a URL should be black-listed if 81a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // there is any occurrence of the key value pair. It should be white-listed 82a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // only if every occurrence of the key is followed by the value. This avoids 83a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // situations such as a user appending a white-listed video parameter in the 84a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // end of the query and watching a video of his choice (the last parameter is 85a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // ignored by some web servers like youtube's). 86a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch URLQueryElementMatcherCondition::Type match_type = 87a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch allow ? URLQueryElementMatcherCondition::MATCH_ALL 88a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch : URLQueryElementMatcherCondition::MATCH_ANY; 89a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 90a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch while (ExtractQueryKeyValue(query.data(), &query_left, &key, &value)) { 91a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch URLQueryElementMatcherCondition::QueryElementType query_element_type = 92a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch value.len ? URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE 93a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch : URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY; 94a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch URLQueryElementMatcherCondition::QueryValueMatchType query_value_match_type; 95a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!value.len && key.len && query[key.end() - 1] == '*') { 96a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch --key.len; 97a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch query_value_match_type = 98a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX; 99a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } else if (value.len && query[value.end() - 1] == '*') { 100a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch --value.len; 101a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch query_value_match_type = 102a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX; 103a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } else { 104a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch query_value_match_type = 105a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT; 106a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 107a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch query_conditions->insert( 108a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch URLQueryElementMatcherCondition(query.substr(key.begin, key.len), 109a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch query.substr(value.begin, value.len), 110a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch query_value_match_type, 111a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch query_element_type, 112a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch match_type, 113a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch condition_factory)); 114a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 115a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 116a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 11703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool BypassBlacklistWildcardForURL(const GURL& url) { 11803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const std::string& scheme = url.scheme(); 11903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) for (size_t i = 0; i < arraysize(kBypassBlacklistWildcardForSchemes); ++i) { 12003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (scheme == kBypassBlacklistWildcardForSchemes[i]) 12103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return true; 12203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 12303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return false; 12403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 12503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct URLBlacklist::FilterComponents { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilterComponents() : port(0), match_subdomains(true), allow(true) {} 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~FilterComponents() {} 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Returns true if |this| represents the "*" filter in the blacklist. 13303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool IsBlacklistWildcard() const { 13403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return !allow && host.empty() && scheme.empty() && path.empty() && 13503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) query.empty() && port == 0 && number_of_key_value_pairs == 0 && 13603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) match_subdomains; 13703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 13803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string scheme; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string host; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16 port; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string path; 143a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch std::string query; 144a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch int number_of_key_value_pairs; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool match_subdomains; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool allow; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)URLBlacklist::URLBlacklist(SegmentURLCallback segment_url) 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : segment_url_(segment_url), id_(0), url_matcher_(new URLMatcher) {} 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)URLBlacklist::~URLBlacklist() {} 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLBlacklist::AddFilters(bool allow, 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::ListValue* list) { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLMatcherConditionSet::Vector all_conditions; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t size = std::min(kMaxFiltersPerPolicy, list->GetSize()); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < size; ++i) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string pattern; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success = list->GetString(i, &pattern); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(success); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilterComponents components; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) components.allow = allow; 164a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!FilterToComponents(segment_url_, 165a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch pattern, 166a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch &components.scheme, 167a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch &components.host, 168a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch &components.match_subdomains, 169a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch &components.port, 170a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch &components.path, 171a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch &components.query)) { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Invalid pattern " << pattern; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 176a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch scoped_refptr<URLMatcherConditionSet> condition_set = 177a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch CreateConditionSet(url_matcher_.get(), 178a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ++id_, 179a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch components.scheme, 180a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch components.host, 181a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch components.match_subdomains, 182a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch components.port, 183a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch components.path, 184a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch components.query, 185a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch allow); 186a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch components.number_of_key_value_pairs = 187a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch condition_set->query_conditions().size(); 188a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch all_conditions.push_back(condition_set); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filters_[id_] = components; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_matcher_->AddConditionSets(all_conditions); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLBlacklist::Block(const base::ListValue* filters) { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddFilters(false, filters); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLBlacklist::Allow(const base::ListValue* filters) { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddFilters(true, filters); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLBlacklist::IsURLBlocked(const GURL& url) const { 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<URLMatcherConditionSet::ID> matching_ids = 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_matcher_->MatchURL(url); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FilterComponents* max = NULL; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::set<URLMatcherConditionSet::ID>::iterator id = matching_ids.begin(); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id != matching_ids.end(); ++id) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<int, FilterComponents>::const_iterator it = filters_.find(*id); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(it != filters_.end()); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FilterComponents& filter = it->second; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!max || FilterTakesPrecedence(filter, *max)) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max = &filter; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Default to allow. 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!max) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Some of the internal Chrome URLs are not affected by the "*" in the 22103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // blacklist. Note that the "*" is the lowest priority filter possible, so 22203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // any higher priority filter will be applied first. 22303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (max->IsBlacklistWildcard() && BypassBlacklistWildcardForURL(url)) 22403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return false; 22503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !max->allow; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t URLBlacklist::Size() const { 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return filters_.size(); 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool URLBlacklist::FilterToComponents(SegmentURLCallback segment_url, 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& filter, 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* scheme, 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* host, 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* match_subdomains, 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16* port, 240a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch std::string* path, 241a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch std::string* query) { 242010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) url::Parsed parsed; 243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 24403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (segment_url(filter, &parsed) == url::kFileScheme) { 245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::FilePath file_path; 246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!net::FileURLToFilePath(GURL(filter), &file_path)) 247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return false; 248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 24903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) *scheme = url::kFileScheme; 250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) host->clear(); 251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *match_subdomains = true; 252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *port = 0; 253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Special path when the |filter| is 'file://*'. 254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *path = (filter == "file://*") ? "" : file_path.AsUTF8Unsafe(); 255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(FILE_PATH_USES_WIN_SEPARATORS) 256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Separators have to be canonicalized on Windows. 257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::replace(path->begin(), path->end(), '\\', '/'); 258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *path = "/" + *path; 259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif 260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return true; 261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!parsed.host.is_nonempty()) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parsed.scheme.is_nonempty()) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheme->assign(filter, parsed.scheme.begin, parsed.scheme.len); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheme->clear(); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host->assign(filter, parsed.host.begin, parsed.host.len); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Special '*' host, matches all hosts. 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*host == "*") { 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host->clear(); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *match_subdomains = true; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((*host)[0] == '.') { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A leading dot in the pattern syntax means that we don't want to match 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // subdomains. 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host->erase(0, 1); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *match_subdomains = false; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 282010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) url::RawCanonOutputT<char> output; 283010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) url::CanonHostInfo host_info; 284010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) url::CanonicalizeHostVerbose(filter.c_str(), parsed.host, &output, 285010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) &host_info); 286010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (host_info.family == url::CanonHostInfo::NEUTRAL) { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We want to match subdomains. Add a dot in front to make sure we only 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // match at domain component boundaries. 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *host = "." + *host; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *match_subdomains = true; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *match_subdomains = false; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parsed.port.is_nonempty()) { 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int int_port; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!base::StringToInt(filter.substr(parsed.port.begin, parsed.port.len), 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &int_port)) { 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (int_port <= 0 || int_port > kuint16max) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *port = int_port; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Match any port. 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *port = 0; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parsed.path.is_nonempty()) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path->assign(filter, parsed.path.begin, parsed.path.len); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path->clear(); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (query) { 316a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (parsed.query.is_nonempty()) 317a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch query->assign(filter, parsed.query.begin, parsed.query.len); 318a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch else 319a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch query->clear(); 320a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 321a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)scoped_refptr<URLMatcherConditionSet> URLBlacklist::CreateConditionSet( 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) URLMatcher* url_matcher, 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int id, 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& scheme, 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& host, 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool match_subdomains, 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16 port, 333a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const std::string& path, 334a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const std::string& query, 335a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch bool allow) { 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLMatcherConditionFactory* condition_factory = 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_matcher->condition_factory(); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<URLMatcherCondition> conditions; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) conditions.insert(match_subdomains ? 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) condition_factory->CreateHostSuffixPathPrefixCondition(host, path) : 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) condition_factory->CreateHostEqualsPathPrefixCondition(host, path)); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 343a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch std::set<URLQueryElementMatcherCondition> query_conditions; 344a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!query.empty()) { 345a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ProcessQueryToConditions( 346a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch condition_factory, query, allow, &query_conditions); 347a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 348a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<URLMatcherSchemeFilter> scheme_filter; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!scheme.empty()) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheme_filter.reset(new URLMatcherSchemeFilter(scheme)); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<URLMatcherPortFilter> port_filter; 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (port != 0) { 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<URLMatcherPortFilter::Range> ranges; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ranges.push_back(URLMatcherPortFilter::CreateRange(port)); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) port_filter.reset(new URLMatcherPortFilter(ranges)); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 360a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return new URLMatcherConditionSet(id, 361a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch conditions, 362a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch query_conditions, 363a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch scheme_filter.Pass(), 364a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch port_filter.Pass()); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLBlacklist::FilterTakesPrecedence(const FilterComponents& lhs, 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FilterComponents& rhs) { 37003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // The "*" wildcard is the lowest priority filter. 37103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (rhs.IsBlacklistWildcard()) 37203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return true; 37303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (lhs.match_subdomains && !rhs.match_subdomains) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!lhs.match_subdomains && rhs.match_subdomains) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t host_length = lhs.host.length(); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t other_host_length = rhs.host.length(); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host_length != other_host_length) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return host_length > other_host_length; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t path_length = lhs.path.length(); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t other_path_length = rhs.path.length(); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (path_length != other_path_length) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return path_length > other_path_length; 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 389a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (lhs.number_of_key_value_pairs != rhs.number_of_key_value_pairs) 390a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return lhs.number_of_key_value_pairs > rhs.number_of_key_value_pairs; 391a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (lhs.allow && !rhs.allow) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)URLBlacklistManager::URLBlacklistManager( 3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PrefService* pref_service, 4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const scoped_refptr<base::SequencedTaskRunner>& background_task_runner, 4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const scoped_refptr<base::SequencedTaskRunner>& io_task_runner, 4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) URLBlacklist::SegmentURLCallback segment_url, 403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OverrideBlacklistCallback override_blacklist) 4041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : pref_service_(pref_service), 4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) background_task_runner_(background_task_runner), 4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) io_task_runner_(io_task_runner), 4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) segment_url_(segment_url), 408a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) override_blacklist_(override_blacklist), 4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui_task_runner_(base::MessageLoopProxy::current()), 4101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci blacklist_(new URLBlacklist(segment_url)), 4111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ui_weak_ptr_factory_(this), 4121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci io_weak_ptr_factory_(this) { 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref_change_registrar_.Init(pref_service_); 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Closure callback = base::Bind(&URLBlacklistManager::ScheduleUpdate, 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this)); 4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pref_change_registrar_.Add(policy_prefs::kUrlBlacklist, callback); 4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pref_change_registrar_.Add(policy_prefs::kUrlWhitelist, callback); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start enforcing the policies without a delay when they are present at 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // startup. 4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (pref_service_->HasPrefPath(policy_prefs::kUrlBlacklist)) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Update(); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLBlacklistManager::ShutdownOnUIThread() { 4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cancel any pending updates, and stop listening for pref change updates. 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_weak_ptr_factory_.InvalidateWeakPtrs(); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref_change_registrar_.RemoveAll(); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLBlacklistManager::~URLBlacklistManager() { 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLBlacklistManager::ScheduleUpdate() { 4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cancel pending updates, if any. This can happen if two preferences that 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // change the blacklist are updated in one message loop cycle. In those cases, 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // only rebuild the blacklist after all the preference updates are processed. 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_weak_ptr_factory_.InvalidateWeakPtrs(); 4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui_task_runner_->PostTask( 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&URLBlacklistManager::Update, 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_weak_ptr_factory_.GetWeakPtr())); 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLBlacklistManager::Update() { 4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The preferences can only be read on the UI thread. 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::ListValue> block( 4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pref_service_->GetList(policy_prefs::kUrlBlacklist)->DeepCopy()); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::ListValue> allow( 4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pref_service_->GetList(policy_prefs::kUrlWhitelist)->DeepCopy()); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Go through the IO thread to grab a WeakPtr to |this|. This is safe from 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // here, since this task will always execute before a potential deletion of 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ProfileIOData on IO. 4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) io_task_runner_->PostTask(FROM_HERE, 4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&URLBlacklistManager::UpdateOnIO, 4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Unretained(this), 4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Passed(&block), 4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Passed(&allow))); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLBlacklistManager::UpdateOnIO(scoped_ptr<base::ListValue> block, 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::ListValue> allow) { 4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The URLBlacklist is built on a worker thread. Once it's ready, it is passed 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to the URLBlacklistManager on IO. 4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::PostTaskAndReplyWithResult( 4721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci background_task_runner_.get(), 4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FROM_HERE, 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&BuildBlacklist, 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Passed(&block), 4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Passed(&allow), 4775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) segment_url_), 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&URLBlacklistManager::SetBlacklist, 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_weak_ptr_factory_.GetWeakPtr())); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLBlacklistManager::SetBlacklist(scoped_ptr<URLBlacklist> blacklist) { 4835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blacklist_ = blacklist.Pass(); 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLBlacklistManager::IsURLBlocked(const GURL& url) const { 4885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return blacklist_->IsURLBlocked(url); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool URLBlacklistManager::IsRequestBlocked( 493c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const net::URLRequest& request, int* reason) const { 4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 4955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if !defined(OS_IOS) 4965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(joaodasilva): iOS doesn't set these flags. http://crbug.com/338283 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int filter_flags = net::LOAD_MAIN_FRAME | net::LOAD_SUB_FRAME; 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((request.load_flags() & filter_flags) == 0) 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 502a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool block = false; 503c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (override_blacklist_.Run(request.url(), &block, reason)) 504a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return block; 505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 506c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch *reason = net::ERR_BLOCKED_BY_ADMINISTRATOR; 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return IsURLBlocked(request.url()); 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 5117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid URLBlacklistManager::RegisterProfilePrefs( 512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) user_prefs::PrefRegistrySyncable* registry) { 5135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry->RegisterListPref(policy_prefs::kUrlBlacklist, 514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 5155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry->RegisterListPref(policy_prefs::kUrlWhitelist, 516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace policy 520