OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/policy/url_blacklist_manager.h" | 5 #include "chrome/browser/policy/url_blacklist_manager.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
9 #include "base/string_number_conversions.h" | 9 #include "base/string_number_conversions.h" |
10 #include "base/values.h" | 10 #include "base/values.h" |
(...skipping 11 matching lines...) Expand all Loading... |
22 namespace { | 22 namespace { |
23 | 23 |
24 // Maximum filters per policy. Filters over this index are ignored. | 24 // Maximum filters per policy. Filters over this index are ignored. |
25 const size_t kMaxFiltersPerPolicy = 100; | 25 const size_t kMaxFiltersPerPolicy = 100; |
26 | 26 |
27 typedef std::vector<std::string> StringVector; | 27 typedef std::vector<std::string> StringVector; |
28 | 28 |
29 StringVector* ListValueToStringVector(const base::ListValue* list) { | 29 StringVector* ListValueToStringVector(const base::ListValue* list) { |
30 StringVector* vector = new StringVector; | 30 StringVector* vector = new StringVector; |
31 | 31 |
32 if (!list) | 32 if (list == NULL) |
33 return vector; | 33 return vector; |
34 | 34 |
35 vector->reserve(list->GetSize()); | 35 vector->reserve(list->GetSize()); |
36 std::string s; | 36 std::string s; |
37 for (base::ListValue::const_iterator it = list->begin(); | 37 for (base::ListValue::const_iterator it = list->begin(); |
38 it != list->end() && vector->size() < kMaxFiltersPerPolicy; ++it) { | 38 it != list->end() && vector->size() < kMaxFiltersPerPolicy; ++it) { |
39 if ((*it)->GetAsString(&s)) | 39 if ((*it)->GetAsString(&s)) |
40 vector->push_back(s); | 40 vector->push_back(s); |
41 } | 41 } |
42 | 42 |
(...skipping 16 matching lines...) Expand all Loading... |
59 for (StringVector::iterator it = allow->begin(); it != allow->end(); ++it) { | 59 for (StringVector::iterator it = allow->begin(); it != allow->end(); ++it) { |
60 blacklist->Allow(*it); | 60 blacklist->Allow(*it); |
61 } | 61 } |
62 } | 62 } |
63 | 63 |
64 // A task that owns the URLBlacklist, and passes it to the URLBlacklistManager | 64 // A task that owns the URLBlacklist, and passes it to the URLBlacklistManager |
65 // on the IO thread, if the URLBlacklistManager still exists. | 65 // on the IO thread, if the URLBlacklistManager still exists. |
66 void SetBlacklistOnIO(base::WeakPtr<URLBlacklistManager> blacklist_manager, | 66 void SetBlacklistOnIO(base::WeakPtr<URLBlacklistManager> blacklist_manager, |
67 URLBlacklist* blacklist) { | 67 URLBlacklist* blacklist) { |
68 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 68 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
69 if (blacklist_manager) | 69 if (blacklist_manager) { |
70 blacklist_manager->SetBlacklist(blacklist); | 70 blacklist_manager->SetBlacklist(blacklist); |
71 else | 71 } else { |
72 delete blacklist; | 72 delete blacklist; |
| 73 } |
73 } | 74 } |
74 | 75 |
75 } // namespace | 76 } // namespace |
76 | 77 |
| 78 struct URLBlacklist::PathFilter { |
| 79 explicit PathFilter(const std::string& path, uint16 port, bool match) |
| 80 : path_prefix(path), |
| 81 port(port), |
| 82 blocked_schemes(0), |
| 83 allowed_schemes(0), |
| 84 match_subdomains(match) {} |
| 85 |
| 86 std::string path_prefix; |
| 87 uint16 port; |
| 88 uint8 blocked_schemes; |
| 89 uint8 allowed_schemes; |
| 90 bool match_subdomains; |
| 91 }; |
| 92 |
77 URLBlacklist::URLBlacklist() { | 93 URLBlacklist::URLBlacklist() { |
78 } | 94 } |
79 | 95 |
80 URLBlacklist::~URLBlacklist() { | 96 URLBlacklist::~URLBlacklist() { |
81 STLDeleteValues(&host_filters_); | 97 STLDeleteValues(&host_filters_); |
82 } | 98 } |
83 | 99 |
84 void URLBlacklist::Block(const std::string& filter) { | 100 void URLBlacklist::Block(const std::string& filter) { |
85 AddFilter(filter, true); | 101 AddFilter(filter, true); |
86 } | 102 } |
(...skipping 12 matching lines...) Expand all Loading... |
99 std::string host(url.host()); | 115 std::string host(url.host()); |
100 int int_port = url.EffectiveIntPort(); | 116 int int_port = url.EffectiveIntPort(); |
101 const uint16 port = int_port > 0 ? int_port : 0; | 117 const uint16 port = int_port > 0 ? int_port : 0; |
102 const std::string& path = url.path(); | 118 const std::string& path = url.path(); |
103 | 119 |
104 // The first iteration through the loop will be an exact host match. | 120 // The first iteration through the loop will be an exact host match. |
105 // Subsequent iterations are subdomain matches, and some filters don't apply | 121 // Subsequent iterations are subdomain matches, and some filters don't apply |
106 // to those. | 122 // to those. |
107 bool is_matching_subdomains = false; | 123 bool is_matching_subdomains = false; |
108 const bool host_is_ip = url.HostIsIPAddress(); | 124 const bool host_is_ip = url.HostIsIPAddress(); |
109 for (;;) { | 125 while (1) { |
110 HostFilterTable::const_iterator host_filter = host_filters_.find(host); | 126 HostFilterTable::const_iterator host_filter = host_filters_.find(host); |
111 if (host_filter != host_filters_.end()) { | 127 if (host_filter != host_filters_.end()) { |
112 const PathFilterList* list = host_filter->second; | 128 const PathFilterList* list = host_filter->second; |
113 size_t longest_length = 0; | 129 size_t longest_length = 0; |
114 bool is_blocked = false; | 130 bool is_blocked = false; |
115 bool has_match = false; | 131 bool has_match = false; |
116 bool has_exact_host_match = false; | 132 bool has_exact_host_match = false; |
117 for (PathFilterList::const_iterator it = list->begin(); | 133 for (PathFilterList::const_iterator it = list->begin(); |
118 it != list->end(); ++it) { | 134 it != list->end(); ++it) { |
119 // Filters that apply to an exact hostname only take precedence over | 135 // Filters that apply to an exact hostname only take precedence over |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 ++i; | 188 ++i; |
173 host.erase(0, i); | 189 host.erase(0, i); |
174 } | 190 } |
175 | 191 |
176 // Default is to allow. | 192 // Default is to allow. |
177 return false; | 193 return false; |
178 } | 194 } |
179 | 195 |
180 // static | 196 // static |
181 bool URLBlacklist::SchemeToFlag(const std::string& scheme, SchemeFlag* flag) { | 197 bool URLBlacklist::SchemeToFlag(const std::string& scheme, SchemeFlag* flag) { |
182 if (scheme.empty()) | 198 if (scheme.empty()) { |
183 *flag = SCHEME_ALL; | 199 *flag = SCHEME_ALL; |
184 else if (scheme == "http") | 200 } else if (scheme == "http") { |
185 *flag = SCHEME_HTTP; | 201 *flag = SCHEME_HTTP; |
186 else if (scheme == "https") | 202 } else if (scheme == "https") { |
187 *flag = SCHEME_HTTPS; | 203 *flag = SCHEME_HTTPS; |
188 else if (scheme == "ftp") | 204 } else if (scheme == "ftp") { |
189 *flag = SCHEME_FTP; | 205 *flag = SCHEME_FTP; |
190 else | 206 } else { |
191 return false; | 207 return false; |
| 208 } |
192 return true; | 209 return true; |
193 } | 210 } |
194 | 211 |
195 // static | 212 // static |
196 bool URLBlacklist::FilterToComponents(const std::string& filter, | 213 bool URLBlacklist::FilterToComponents(const std::string& filter, |
197 std::string* scheme, | 214 std::string* scheme, |
198 std::string* host, | 215 std::string* host, |
199 uint16* port, | 216 uint16* port, |
200 std::string* path) { | 217 std::string* path) { |
201 url_parse::Parsed parsed; | 218 url_parse::Parsed parsed; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 path->clear(); | 251 path->clear(); |
235 | 252 |
236 return true; | 253 return true; |
237 } | 254 } |
238 | 255 |
239 void URLBlacklist::AddFilter(const std::string& filter, bool block) { | 256 void URLBlacklist::AddFilter(const std::string& filter, bool block) { |
240 std::string scheme; | 257 std::string scheme; |
241 std::string host; | 258 std::string host; |
242 uint16 port; | 259 uint16 port; |
243 std::string path; | 260 std::string path; |
244 SchemeFlag flag; | |
245 bool match_subdomains = true; | |
246 | |
247 if (!FilterToComponents(filter, &scheme, &host, &port, &path)) { | 261 if (!FilterToComponents(filter, &scheme, &host, &port, &path)) { |
248 LOG(WARNING) << "Invalid filter, ignoring: " << filter; | 262 LOG(WARNING) << "Invalid filter, ignoring: " << filter; |
249 return; | 263 return; |
250 } | 264 } |
251 | 265 |
| 266 SchemeFlag flag; |
252 if (!SchemeToFlag(scheme, &flag)) { | 267 if (!SchemeToFlag(scheme, &flag)) { |
253 LOG(WARNING) << "Unsupported scheme in filter, ignoring filter: " << filter; | 268 LOG(WARNING) << "Unsupported scheme in filter, ignoring filter: " << filter; |
254 return; | 269 return; |
255 } | 270 } |
256 | 271 |
| 272 bool match_subdomains = true; |
257 // Special syntax to disable subdomain matching. | 273 // Special syntax to disable subdomain matching. |
258 if (!host.empty() && host[0] == '.') { | 274 if (!host.empty() && host[0] == '.') { |
259 host.erase(0, 1); | 275 host.erase(0, 1); |
260 match_subdomains = false; | 276 match_subdomains = false; |
261 } | 277 } |
262 | 278 |
263 // Try to find an existing PathFilter with the same path prefix, port and | 279 // Try to find an existing PathFilter with the same path prefix, port and |
264 // match_subdomains value. | 280 // match_subdomains value. |
265 PathFilterList* list; | 281 PathFilterList* list; |
266 HostFilterTable::iterator host_filter = host_filters_.find(host); | 282 HostFilterTable::iterator host_filter = host_filters_.find(host); |
267 if (host_filter == host_filters_.end()) { | 283 if (host_filter == host_filters_.end()) { |
268 list = new PathFilterList; | 284 list = new PathFilterList; |
269 host_filters_[host] = list; | 285 host_filters_[host] = list; |
270 } else { | 286 } else { |
271 list = host_filter->second; | 287 list = host_filter->second; |
272 } | 288 } |
273 PathFilterList::iterator it; | 289 PathFilterList::iterator it; |
274 for (it = list->begin(); it != list->end(); ++it) { | 290 for (it = list->begin(); it != list->end(); ++it) { |
275 if (it->port == port && it->match_subdomains == match_subdomains && | 291 if (it->port == port && it->match_subdomains == match_subdomains && |
276 it->path_prefix == path) | 292 it->path_prefix == path) { |
277 break; | 293 break; |
| 294 } |
278 } | 295 } |
279 PathFilter* path_filter; | 296 PathFilter* path_filter; |
280 if (it == list->end()) { | 297 if (it == list->end()) { |
281 list->push_back(PathFilter(path, port, match_subdomains)); | 298 list->push_back(PathFilter(path, port, match_subdomains)); |
282 path_filter = &list->back(); | 299 path_filter = &list->back(); |
283 } else { | 300 } else { |
284 path_filter = &(*it); | 301 path_filter = &(*it); |
285 } | 302 } |
286 | 303 |
287 if (block) | 304 if (block) { |
288 path_filter->blocked_schemes |= flag; | 305 path_filter->blocked_schemes |= flag; |
289 else | 306 } else { |
290 path_filter->allowed_schemes |= flag; | 307 path_filter->allowed_schemes |= flag; |
| 308 } |
291 } | 309 } |
292 | 310 |
293 URLBlacklistManager::URLBlacklistManager(PrefService* pref_service) | 311 URLBlacklistManager::URLBlacklistManager(PrefService* pref_service) |
294 : ALLOW_THIS_IN_INITIALIZER_LIST(ui_weak_ptr_factory_(this)), | 312 : ALLOW_THIS_IN_INITIALIZER_LIST(ui_weak_ptr_factory_(this)), |
295 pref_service_(pref_service), | 313 pref_service_(pref_service), |
296 ALLOW_THIS_IN_INITIALIZER_LIST(io_weak_ptr_factory_(this)), | 314 ALLOW_THIS_IN_INITIALIZER_LIST(io_weak_ptr_factory_(this)), |
297 blacklist_(new URLBlacklist) { | 315 blacklist_(new URLBlacklist) { |
298 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 316 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
299 | 317 |
300 pref_change_registrar_.Init(pref_service_); | 318 pref_change_registrar_.Init(pref_service_); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 | 404 |
387 // static | 405 // static |
388 void URLBlacklistManager::RegisterPrefs(PrefService* pref_service) { | 406 void URLBlacklistManager::RegisterPrefs(PrefService* pref_service) { |
389 pref_service->RegisterListPref(prefs::kUrlBlacklist, | 407 pref_service->RegisterListPref(prefs::kUrlBlacklist, |
390 PrefService::UNSYNCABLE_PREF); | 408 PrefService::UNSYNCABLE_PREF); |
391 pref_service->RegisterListPref(prefs::kUrlWhitelist, | 409 pref_service->RegisterListPref(prefs::kUrlWhitelist, |
392 PrefService::UNSYNCABLE_PREF); | 410 PrefService::UNSYNCABLE_PREF); |
393 } | 411 } |
394 | 412 |
395 } // namespace policy | 413 } // namespace policy |
OLD | NEW |