Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Side by Side Diff: chrome/browser/safe_browsing/safe_browsing_service.cc

Issue 7383012: Start and stop the safe browsing service depending on whether any profile is using it. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/safe_browsing/safe_browsing_service.h" 5 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
10 #include "base/path_service.h" 10 #include "base/path_service.h"
11 #include "base/stl_util-inl.h" 11 #include "base/stl_util-inl.h"
12 #include "base/string_util.h" 12 #include "base/string_util.h"
13 #include "base/threading/thread_restrictions.h" 13 #include "base/threading/thread_restrictions.h"
14 #include "chrome/browser/browser_process.h" 14 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/metrics/metrics_service.h" 15 #include "chrome/browser/metrics/metrics_service.h"
16 #include "chrome/browser/prefs/pref_change_registrar.h"
16 #include "chrome/browser/prefs/pref_service.h" 17 #include "chrome/browser/prefs/pref_service.h"
17 #include "chrome/browser/profiles/profile.h" 18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/profiles/profile_manager.h"
18 #include "chrome/browser/safe_browsing/malware_details.h" 20 #include "chrome/browser/safe_browsing/malware_details.h"
19 #include "chrome/browser/safe_browsing/protocol_manager.h" 21 #include "chrome/browser/safe_browsing/protocol_manager.h"
20 #include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h" 22 #include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h"
21 #include "chrome/browser/safe_browsing/safe_browsing_database.h" 23 #include "chrome/browser/safe_browsing/safe_browsing_database.h"
22 #include "chrome/browser/tab_contents/tab_util.h" 24 #include "chrome/browser/tab_contents/tab_util.h"
23 #include "chrome/common/chrome_constants.h" 25 #include "chrome/common/chrome_constants.h"
26 #include "chrome/common/chrome_notification_types.h"
24 #include "chrome/common/chrome_paths.h" 27 #include "chrome/common/chrome_paths.h"
25 #include "chrome/common/chrome_switches.h" 28 #include "chrome/common/chrome_switches.h"
26 #include "chrome/common/pref_names.h" 29 #include "chrome/common/pref_names.h"
27 #include "chrome/common/url_constants.h" 30 #include "chrome/common/url_constants.h"
28 #include "content/browser/browser_thread.h" 31 #include "content/browser/browser_thread.h"
29 #include "content/browser/tab_contents/tab_contents.h" 32 #include "content/browser/tab_contents/tab_contents.h"
33 #include "content/common/content_notification_types.h"
30 #include "content/common/notification_service.h" 34 #include "content/common/notification_service.h"
31 #include "net/base/registry_controlled_domain.h" 35 #include "net/base/registry_controlled_domain.h"
32 #include "net/url_request/url_request_context_getter.h" 36 #include "net/url_request/url_request_context_getter.h"
33 37
34 #if defined(OS_WIN) 38 #if defined(OS_WIN)
35 #include "chrome/installer/util/browser_distribution.h" 39 #include "chrome/installer/util/browser_distribution.h"
36 #endif 40 #endif
37 41
38 namespace { 42 namespace {
39 43
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 enable_download_protection_(false), 161 enable_download_protection_(false),
158 enable_csd_whitelist_(false), 162 enable_csd_whitelist_(false),
159 update_in_progress_(false), 163 update_in_progress_(false),
160 database_update_in_progress_(false), 164 database_update_in_progress_(false),
161 closing_database_(false), 165 closing_database_(false),
162 download_urlcheck_timeout_ms_(kDownloadUrlCheckTimeoutMs), 166 download_urlcheck_timeout_ms_(kDownloadUrlCheckTimeoutMs),
163 download_hashcheck_timeout_ms_(kDownloadHashCheckTimeoutMs) { 167 download_hashcheck_timeout_ms_(kDownloadHashCheckTimeoutMs) {
164 } 168 }
165 169
166 void SafeBrowsingService::Initialize() { 170 void SafeBrowsingService::Initialize() {
167 // Always initialize the safe browsing service. Each profile will decide 171 // Track the safe browsing preference of existing profiles.
168 // whether to use it based on per-user preferences. TODO(mirandac): in 172 // The SafeBrowsingService will be started if any existing profile has the
169 // follow-up CL, only initialize if a profile is launched for which safe 173 // preference enabled. It will also listen for updates to the preferences.
170 // browsing is enabled. see http://crbug.com/88661 174 ProfileManager* profile_manager = g_browser_process->profile_manager();
171 Start(); 175 if (profile_manager) {
176 std::vector<Profile*> profiles = profile_manager->GetLoadedProfiles();
177 for (size_t i = 0; i < profiles.size(); ++i) {
178 if (profiles[i]->IsOffTheRecord())
179 continue;
180 AddPrefService(profiles[i]->GetPrefs());
181 }
182 }
183
184 // Track profile creation and destruction.
185 prefs_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED,
186 NotificationService::AllSources());
187 prefs_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
188 NotificationService::AllSources());
172 } 189 }
173 190
174 void SafeBrowsingService::ShutDown() { 191 void SafeBrowsingService::ShutDown() {
175 BrowserThread::PostTask( 192 BrowserThread::PostTask(
176 BrowserThread::IO, FROM_HERE, 193 BrowserThread::IO, FROM_HERE,
177 NewRunnableMethod(this, &SafeBrowsingService::OnIOShutdown)); 194 NewRunnableMethod(this, &SafeBrowsingService::OnIOShutdown));
178 } 195 }
179 196
180 bool SafeBrowsingService::CanCheckUrl(const GURL& url) const { 197 bool SafeBrowsingService::CanCheckUrl(const GURL& url) const {
181 return url.SchemeIs(chrome::kFtpScheme) || 198 return url.SchemeIs(chrome::kFtpScheme) ||
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 457
441 void SafeBrowsingService::OnNewMacKeys(const std::string& client_key, 458 void SafeBrowsingService::OnNewMacKeys(const std::string& client_key,
442 const std::string& wrapped_key) { 459 const std::string& wrapped_key) {
443 PrefService* prefs = g_browser_process->local_state(); 460 PrefService* prefs = g_browser_process->local_state();
444 if (prefs) { 461 if (prefs) {
445 prefs->SetString(prefs::kSafeBrowsingClientKey, client_key); 462 prefs->SetString(prefs::kSafeBrowsingClientKey, client_key);
446 prefs->SetString(prefs::kSafeBrowsingWrappedKey, wrapped_key); 463 prefs->SetString(prefs::kSafeBrowsingWrappedKey, wrapped_key);
447 } 464 }
448 } 465 }
449 466
450 void SafeBrowsingService::OnEnable(bool enabled) {
451 if (enabled)
452 Start();
453 else
454 ShutDown();
455 }
456
457 // static 467 // static
458 void SafeBrowsingService::RegisterPrefs(PrefService* prefs) { 468 void SafeBrowsingService::RegisterPrefs(PrefService* prefs) {
459 prefs->RegisterStringPref(prefs::kSafeBrowsingClientKey, ""); 469 prefs->RegisterStringPref(prefs::kSafeBrowsingClientKey, "");
460 prefs->RegisterStringPref(prefs::kSafeBrowsingWrappedKey, ""); 470 prefs->RegisterStringPref(prefs::kSafeBrowsingWrappedKey, "");
461 } 471 }
462 472
463 void SafeBrowsingService::ResetDatabase() { 473 void SafeBrowsingService::ResetDatabase() {
464 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 474 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
465 DCHECK(enabled_); 475 DCHECK(enabled_);
466 safe_browsing_thread_->message_loop()->PostTask(FROM_HERE, NewRunnableMethod( 476 safe_browsing_thread_->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
467 this, &SafeBrowsingService::OnResetDatabase)); 477 this, &SafeBrowsingService::OnResetDatabase));
468 } 478 }
469 479
470 void SafeBrowsingService::LogPauseDelay(base::TimeDelta time) { 480 void SafeBrowsingService::LogPauseDelay(base::TimeDelta time) {
471 UMA_HISTOGRAM_LONG_TIMES("SB2.Delay", time); 481 UMA_HISTOGRAM_LONG_TIMES("SB2.Delay", time);
472 } 482 }
473 483
474 SafeBrowsingService::~SafeBrowsingService() { 484 SafeBrowsingService::~SafeBrowsingService() {
475 // We should have already been shut down. If we're still enabled, then the 485 // Deletes the PrefChangeRegistrars, whose dtors also unregister |this| as an
486 // observer of the preferences.
487 STLDeleteValues(&prefs_map_);
488
489 // We should have already been shut down. If we're still enabled, then the
476 // database isn't going to be closed properly, which could lead to corruption. 490 // database isn't going to be closed properly, which could lead to corruption.
477 DCHECK(!enabled_); 491 DCHECK(!enabled_);
478 } 492 }
479 493
480 void SafeBrowsingService::OnIOInitialize( 494 void SafeBrowsingService::OnIOInitialize(
481 const std::string& client_key, 495 const std::string& client_key,
482 const std::string& wrapped_key, 496 const std::string& wrapped_key,
483 net::URLRequestContextGetter* request_context_getter) { 497 net::URLRequestContextGetter* request_context_getter) {
484 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 498 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
499 if (enabled_)
500 return;
501 DCHECK(!safe_browsing_thread_.get());
502 safe_browsing_thread_.reset(new base::Thread("Chrome_SafeBrowsingThread"));
503 if (!safe_browsing_thread_->Start())
504 return;
485 enabled_ = true; 505 enabled_ = true;
486 506
487 registrar_.Add(this, content::NOTIFICATION_PURGE_MEMORY, 507 registrar_.Add(this, content::NOTIFICATION_PURGE_MEMORY,
488 NotificationService::AllSources()); 508 NotificationService::AllSources());
489 509
490 MakeDatabaseAvailable(); 510 MakeDatabaseAvailable();
491 511
492 // On Windows, get the safe browsing client name from the browser 512 // On Windows, get the safe browsing client name from the browser
493 // distribution classes in installer util. These classes don't yet have 513 // distribution classes in installer util. These classes don't yet have
494 // an analog on non-Windows builds so just keep the name specified here. 514 // an analog on non-Windows builds so just keep the name specified here.
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
829 849
830 void SafeBrowsingService::DatabaseUpdateFinished(bool update_succeeded) { 850 void SafeBrowsingService::DatabaseUpdateFinished(bool update_succeeded) {
831 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop()); 851 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop());
832 GetDatabase()->UpdateFinished(update_succeeded); 852 GetDatabase()->UpdateFinished(update_succeeded);
833 DCHECK(database_update_in_progress_); 853 DCHECK(database_update_in_progress_);
834 database_update_in_progress_ = false; 854 database_update_in_progress_ = false;
835 } 855 }
836 856
837 void SafeBrowsingService::Start() { 857 void SafeBrowsingService::Start() {
838 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 858 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
839 DCHECK(!safe_browsing_thread_.get());
840 safe_browsing_thread_.reset(new base::Thread("Chrome_SafeBrowsingThread"));
841 if (!safe_browsing_thread_->Start())
842 return;
843 859
844 // Retrieve client MAC keys. 860 // Retrieve client MAC keys.
845 PrefService* local_state = g_browser_process->local_state(); 861 PrefService* local_state = g_browser_process->local_state();
846 DCHECK(local_state); 862 DCHECK(local_state);
847 std::string client_key, wrapped_key; 863 std::string client_key, wrapped_key;
848 if (local_state) { 864 if (local_state) {
849 client_key = 865 client_key =
850 local_state->GetString(prefs::kSafeBrowsingClientKey); 866 local_state->GetString(prefs::kSafeBrowsingClientKey);
851 wrapped_key = 867 wrapped_key =
852 local_state->GetString(prefs::kSafeBrowsingWrappedKey); 868 local_state->GetString(prefs::kSafeBrowsingWrappedKey);
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after
1196 entry.render_view_id = resource.render_view_id; 1212 entry.render_view_id = resource.render_view_id;
1197 entry.domain = net::RegistryControlledDomainService::GetDomainAndRegistry( 1213 entry.domain = net::RegistryControlledDomainService::GetDomainAndRegistry(
1198 resource.url); 1214 resource.url);
1199 entry.result = resource.threat_type; 1215 entry.result = resource.threat_type;
1200 white_listed_entries_.push_back(entry); 1216 white_listed_entries_.push_back(entry);
1201 } 1217 }
1202 1218
1203 void SafeBrowsingService::Observe(int type, 1219 void SafeBrowsingService::Observe(int type,
1204 const NotificationSource& source, 1220 const NotificationSource& source,
1205 const NotificationDetails& details) { 1221 const NotificationDetails& details) {
1206 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1222 switch (type) {
1207 DCHECK(type == content::NOTIFICATION_PURGE_MEMORY); 1223 case chrome::NOTIFICATION_PROFILE_CREATED: {
1208 CloseDatabase(); 1224 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1225 Profile* profile = Source<Profile>(source).ptr();
1226 if (!profile->IsOffTheRecord())
1227 AddPrefService(profile->GetPrefs());
1228 break;
1229 }
1230 case chrome::NOTIFICATION_PROFILE_DESTROYED: {
1231 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1232 Profile* profile = Source<Profile>(source).ptr();
1233 if (!profile->IsOffTheRecord())
1234 RemovePrefService(profile->GetPrefs());
1235 break;
1236 }
1237 case chrome::NOTIFICATION_PREF_CHANGED: {
1238 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1239 std::string* pref = Details<std::string>(details).ptr();
1240 DCHECK(*pref == prefs::kSafeBrowsingEnabled);
1241 RefreshState();
1242 break;
1243 }
1244 case content::NOTIFICATION_PURGE_MEMORY:
1245 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1246 CloseDatabase();
1247 break;
1248 default:
1249 NOTREACHED();
1250 }
1209 } 1251 }
1210 1252
1211 bool SafeBrowsingService::IsWhitelisted(const UnsafeResource& resource) { 1253 bool SafeBrowsingService::IsWhitelisted(const UnsafeResource& resource) {
1212 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1254 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1213 // Check if the user has already ignored our warning for this render_view 1255 // Check if the user has already ignored our warning for this render_view
1214 // and domain. 1256 // and domain.
1215 for (size_t i = 0; i < white_listed_entries_.size(); ++i) { 1257 for (size_t i = 0; i < white_listed_entries_.size(); ++i) {
1216 const WhiteListedEntry& entry = white_listed_entries_[i]; 1258 const WhiteListedEntry& entry = white_listed_entries_[i];
1217 if (entry.render_process_host_id == resource.render_process_host_id && 1259 if (entry.render_process_host_id == resource.render_process_host_id &&
1218 entry.render_view_id == resource.render_view_id && 1260 entry.render_view_id == resource.render_view_id &&
1219 // Threat type must be the same or in the case of phishing they can 1261 // Threat type must be the same or in the case of phishing they can
1220 // either be client-side phishing URL or a SafeBrowsing phishing URL. 1262 // either be client-side phishing URL or a SafeBrowsing phishing URL.
1221 // If we show one type of phishing warning we don't want to show a 1263 // If we show one type of phishing warning we don't want to show a
1222 // second phishing warning. 1264 // second phishing warning.
1223 (entry.result == resource.threat_type || 1265 (entry.result == resource.threat_type ||
1224 (entry.result == URL_PHISHING && 1266 (entry.result == URL_PHISHING &&
1225 resource.threat_type == CLIENT_SIDE_PHISHING_URL) || 1267 resource.threat_type == CLIENT_SIDE_PHISHING_URL) ||
1226 (entry.result == CLIENT_SIDE_PHISHING_URL && 1268 (entry.result == CLIENT_SIDE_PHISHING_URL &&
1227 resource.threat_type == URL_PHISHING)) && 1269 resource.threat_type == URL_PHISHING)) &&
1228 entry.domain == 1270 entry.domain ==
1229 net::RegistryControlledDomainService::GetDomainAndRegistry( 1271 net::RegistryControlledDomainService::GetDomainAndRegistry(
1230 resource.url)) { 1272 resource.url)) {
1231 return true; 1273 return true;
1232 } 1274 }
1233 } 1275 }
1234 return false; 1276 return false;
1235 } 1277 }
1278
1279 void SafeBrowsingService::AddPrefService(PrefService* pref_service) {
1280 DCHECK(prefs_map_.find(pref_service) == prefs_map_.end());
1281 PrefChangeRegistrar* registrar = new PrefChangeRegistrar();
1282 registrar->Init(pref_service);
1283 registrar->Add(prefs::kSafeBrowsingEnabled, this);
1284 prefs_map_[pref_service] = registrar;
1285 RefreshState();
1286 }
1287
1288 void SafeBrowsingService::RemovePrefService(PrefService* pref_service) {
1289 if (prefs_map_.find(pref_service) != prefs_map_.end()) {
1290 delete prefs_map_[pref_service];
1291 prefs_map_.erase(pref_service);
1292 RefreshState();
1293 } else {
1294 NOTREACHED();
1295 }
1296 }
1297
1298 void SafeBrowsingService::RefreshState() {
1299 // Check if any profile requires the service to be active.
1300 bool enable = false;
1301 std::map<PrefService*, PrefChangeRegistrar*>::iterator iter;
1302 for (iter = prefs_map_.begin(); iter != prefs_map_.end(); ++iter) {
1303 if (iter->first->GetBoolean(prefs::kSafeBrowsingEnabled)) {
1304 enable = true;
1305 break;
1306 }
1307 }
1308
1309 if (enable)
1310 Start();
1311 else
1312 ShutDown();
1313 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698