1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/safe_browsing/safe_browsing_service.h" 6 7 #include <vector> 8 9 #include "base/bind.h" 10 #include "base/bind_helpers.h" 11 #include "base/callback.h" 12 #include "base/command_line.h" 13 #include "base/debug/leak_tracker.h" 14 #include "base/lazy_instance.h" 15 #include "base/path_service.h" 16 #include "base/prefs/pref_change_registrar.h" 17 #include "base/prefs/pref_service.h" 18 #include "base/stl_util.h" 19 #include "base/strings/string_util.h" 20 #include "base/threading/thread.h" 21 #include "base/threading/thread_restrictions.h" 22 #include "chrome/browser/browser_process.h" 23 #include "chrome/browser/chrome_notification_types.h" 24 #include "chrome/browser/prefs/tracked/tracked_preference_validation_delegate.h" 25 #include "chrome/browser/profiles/profile.h" 26 #include "chrome/browser/profiles/profile_manager.h" 27 #include "chrome/browser/safe_browsing/client_side_detection_service.h" 28 #include "chrome/browser/safe_browsing/database_manager.h" 29 #include "chrome/browser/safe_browsing/download_protection_service.h" 30 #include "chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer.h" 31 #include "chrome/browser/safe_browsing/incident_reporting/blacklist_load_analyzer.h" 32 #include "chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h" 33 #include "chrome/browser/safe_browsing/malware_details.h" 34 #include "chrome/browser/safe_browsing/ping_manager.h" 35 #include "chrome/browser/safe_browsing/protocol_manager.h" 36 #include "chrome/browser/safe_browsing/safe_browsing_database.h" 37 #include "chrome/browser/safe_browsing/ui_manager.h" 38 #include "chrome/common/chrome_constants.h" 39 #include "chrome/common/chrome_paths.h" 40 #include "chrome/common/chrome_switches.h" 41 #include "chrome/common/pref_names.h" 42 #include "chrome/common/url_constants.h" 43 #include "components/metrics/metrics_service.h" 44 #include "components/startup_metric_utils/startup_metric_utils.h" 45 #include "content/public/browser/browser_thread.h" 46 #include "content/public/browser/cookie_crypto_delegate.h" 47 #include "content/public/browser/cookie_store_factory.h" 48 #include "content/public/browser/notification_service.h" 49 #include "net/cookies/cookie_monster.h" 50 #include "net/url_request/url_request_context.h" 51 #include "net/url_request/url_request_context_getter.h" 52 53 #if defined(OS_WIN) 54 #include "chrome/installer/util/browser_distribution.h" 55 #endif 56 57 #if defined(OS_ANDROID) 58 #include <string> 59 #include "base/metrics/field_trial.h" 60 #endif 61 62 using content::BrowserThread; 63 64 namespace { 65 66 // Filename suffix for the cookie database. 67 const base::FilePath::CharType kCookiesFile[] = FILE_PATH_LITERAL(" Cookies"); 68 69 // The default URL prefix where browser fetches chunk updates, hashes, 70 // and reports safe browsing hits and malware details. 71 const char* const kSbDefaultURLPrefix = 72 "https://safebrowsing.google.com/safebrowsing"; 73 74 // The backup URL prefix used when there are issues establishing a connection 75 // with the server at the primary URL. 76 const char* const kSbBackupConnectErrorURLPrefix = 77 "https://alt1-safebrowsing.google.com/safebrowsing"; 78 79 // The backup URL prefix used when there are HTTP-specific issues with the 80 // server at the primary URL. 81 const char* const kSbBackupHttpErrorURLPrefix = 82 "https://alt2-safebrowsing.google.com/safebrowsing"; 83 84 // The backup URL prefix used when there are local network specific issues. 85 const char* const kSbBackupNetworkErrorURLPrefix = 86 "https://alt3-safebrowsing.google.com/safebrowsing"; 87 88 base::FilePath CookieFilePath() { 89 return base::FilePath( 90 SafeBrowsingService::GetBaseFilename().value() + kCookiesFile); 91 } 92 93 #if defined(FULL_SAFE_BROWSING) 94 // Returns true if the incident reporting service is enabled via a field trial. 95 bool IsIncidentReportingServiceEnabled() { 96 const std::string group_name = base::FieldTrialList::FindFullName( 97 "SafeBrowsingIncidentReportingService"); 98 return group_name == "Enabled"; 99 } 100 #endif // defined(FULL_SAFE_BROWSING) 101 102 } // namespace 103 104 class SafeBrowsingURLRequestContextGetter 105 : public net::URLRequestContextGetter { 106 public: 107 explicit SafeBrowsingURLRequestContextGetter( 108 SafeBrowsingService* sb_service_); 109 110 // Implementation for net::UrlRequestContextGetter. 111 virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE; 112 virtual scoped_refptr<base::SingleThreadTaskRunner> 113 GetNetworkTaskRunner() const OVERRIDE; 114 115 protected: 116 virtual ~SafeBrowsingURLRequestContextGetter(); 117 118 private: 119 SafeBrowsingService* const sb_service_; // Owned by BrowserProcess. 120 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_; 121 122 base::debug::LeakTracker<SafeBrowsingURLRequestContextGetter> leak_tracker_; 123 }; 124 125 SafeBrowsingURLRequestContextGetter::SafeBrowsingURLRequestContextGetter( 126 SafeBrowsingService* sb_service) 127 : sb_service_(sb_service), 128 network_task_runner_( 129 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)) { 130 } 131 132 SafeBrowsingURLRequestContextGetter::~SafeBrowsingURLRequestContextGetter() {} 133 134 net::URLRequestContext* 135 SafeBrowsingURLRequestContextGetter::GetURLRequestContext() { 136 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 137 DCHECK(sb_service_->url_request_context_.get()); 138 139 return sb_service_->url_request_context_.get(); 140 } 141 142 scoped_refptr<base::SingleThreadTaskRunner> 143 SafeBrowsingURLRequestContextGetter::GetNetworkTaskRunner() const { 144 return network_task_runner_; 145 } 146 147 // static 148 SafeBrowsingServiceFactory* SafeBrowsingService::factory_ = NULL; 149 150 // The default SafeBrowsingServiceFactory. Global, made a singleton so we 151 // don't leak it. 152 class SafeBrowsingServiceFactoryImpl : public SafeBrowsingServiceFactory { 153 public: 154 virtual SafeBrowsingService* CreateSafeBrowsingService() OVERRIDE { 155 return new SafeBrowsingService(); 156 } 157 158 private: 159 friend struct base::DefaultLazyInstanceTraits<SafeBrowsingServiceFactoryImpl>; 160 161 SafeBrowsingServiceFactoryImpl() { } 162 163 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceFactoryImpl); 164 }; 165 166 static base::LazyInstance<SafeBrowsingServiceFactoryImpl>::Leaky 167 g_safe_browsing_service_factory_impl = LAZY_INSTANCE_INITIALIZER; 168 169 // static 170 base::FilePath SafeBrowsingService::GetCookieFilePathForTesting() { 171 return CookieFilePath(); 172 } 173 174 // static 175 base::FilePath SafeBrowsingService::GetBaseFilename() { 176 base::FilePath path; 177 bool result = PathService::Get(chrome::DIR_USER_DATA, &path); 178 DCHECK(result); 179 return path.Append(chrome::kSafeBrowsingBaseFilename); 180 } 181 182 183 // static 184 SafeBrowsingService* SafeBrowsingService::CreateSafeBrowsingService() { 185 if (!factory_) 186 factory_ = g_safe_browsing_service_factory_impl.Pointer(); 187 return factory_->CreateSafeBrowsingService(); 188 } 189 190 #if defined(OS_ANDROID) && defined(FULL_SAFE_BROWSING) 191 // static 192 bool SafeBrowsingService::IsEnabledByFieldTrial() { 193 const std::string experiment_name = 194 base::FieldTrialList::FindFullName("SafeBrowsingAndroid"); 195 return experiment_name == "Enabled"; 196 } 197 #endif 198 199 SafeBrowsingService::SafeBrowsingService() 200 : protocol_manager_(NULL), 201 ping_manager_(NULL), 202 enabled_(false) { 203 } 204 205 SafeBrowsingService::~SafeBrowsingService() { 206 // We should have already been shut down. If we're still enabled, then the 207 // database isn't going to be closed properly, which could lead to corruption. 208 DCHECK(!enabled_); 209 } 210 211 void SafeBrowsingService::Initialize() { 212 startup_metric_utils::ScopedSlowStartupUMA 213 scoped_timer("Startup.SlowStartupSafeBrowsingServiceInitialize"); 214 215 url_request_context_getter_ = 216 new SafeBrowsingURLRequestContextGetter(this); 217 218 ui_manager_ = CreateUIManager(); 219 220 database_manager_ = CreateDatabaseManager(); 221 222 BrowserThread::PostTask( 223 BrowserThread::IO, FROM_HERE, 224 base::Bind( 225 &SafeBrowsingService::InitURLRequestContextOnIOThread, this, 226 make_scoped_refptr(g_browser_process->system_request_context()))); 227 228 #if defined(FULL_SAFE_BROWSING) 229 #if !defined(OS_ANDROID) 230 if (!CommandLine::ForCurrentProcess()->HasSwitch( 231 switches::kDisableClientSidePhishingDetection)) { 232 csd_service_.reset(safe_browsing::ClientSideDetectionService::Create( 233 url_request_context_getter_.get())); 234 } 235 download_service_.reset(new safe_browsing::DownloadProtectionService( 236 this, url_request_context_getter_.get())); 237 #endif 238 239 if (IsIncidentReportingServiceEnabled()) { 240 incident_service_.reset(new safe_browsing::IncidentReportingService( 241 this, url_request_context_getter_)); 242 } 243 #endif 244 245 // Track the safe browsing preference of existing profiles. 246 // The SafeBrowsingService will be started if any existing profile has the 247 // preference enabled. It will also listen for updates to the preferences. 248 ProfileManager* profile_manager = g_browser_process->profile_manager(); 249 if (profile_manager) { 250 std::vector<Profile*> profiles = profile_manager->GetLoadedProfiles(); 251 for (size_t i = 0; i < profiles.size(); ++i) { 252 if (profiles[i]->IsOffTheRecord()) 253 continue; 254 AddPrefService(profiles[i]->GetPrefs()); 255 } 256 } 257 258 // Track profile creation and destruction. 259 prefs_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED, 260 content::NotificationService::AllSources()); 261 prefs_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, 262 content::NotificationService::AllSources()); 263 264 #if defined(FULL_SAFE_BROWSING) 265 // Register all the delayed analysis to the incident reporting service. 266 RegisterAllDelayedAnalysis(); 267 #endif 268 } 269 270 void SafeBrowsingService::ShutDown() { 271 // Deletes the PrefChangeRegistrars, whose dtors also unregister |this| as an 272 // observer of the preferences. 273 STLDeleteValues(&prefs_map_); 274 275 // Remove Profile creation/destruction observers. 276 prefs_registrar_.RemoveAll(); 277 278 Stop(true); 279 // The IO thread is going away, so make sure the ClientSideDetectionService 280 // dtor executes now since it may call the dtor of URLFetcher which relies 281 // on it. 282 csd_service_.reset(); 283 download_service_.reset(); 284 incident_service_.reset(); 285 286 url_request_context_getter_ = NULL; 287 BrowserThread::PostNonNestableTask( 288 BrowserThread::IO, FROM_HERE, 289 base::Bind(&SafeBrowsingService::DestroyURLRequestContextOnIOThread, 290 this)); 291 } 292 293 // Binhash verification is only enabled for UMA users for now. 294 bool SafeBrowsingService::DownloadBinHashNeeded() const { 295 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 296 297 #if defined(FULL_SAFE_BROWSING) 298 return (database_manager_->download_protection_enabled() && 299 ui_manager_->CanReportStats()) || 300 (download_protection_service() && 301 download_protection_service()->enabled()); 302 #else 303 return false; 304 #endif 305 } 306 307 net::URLRequestContextGetter* SafeBrowsingService::url_request_context() { 308 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 309 return url_request_context_getter_.get(); 310 } 311 312 const scoped_refptr<SafeBrowsingUIManager>& 313 SafeBrowsingService::ui_manager() const { 314 return ui_manager_; 315 } 316 317 const scoped_refptr<SafeBrowsingDatabaseManager>& 318 SafeBrowsingService::database_manager() const { 319 return database_manager_; 320 } 321 322 SafeBrowsingProtocolManager* SafeBrowsingService::protocol_manager() const { 323 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 324 return protocol_manager_; 325 } 326 327 SafeBrowsingPingManager* SafeBrowsingService::ping_manager() const { 328 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 329 return ping_manager_; 330 } 331 332 scoped_ptr<TrackedPreferenceValidationDelegate> 333 SafeBrowsingService::CreatePreferenceValidationDelegate( 334 Profile* profile) const { 335 #if defined(FULL_SAFE_BROWSING) 336 if (incident_service_) 337 return incident_service_->CreatePreferenceValidationDelegate(profile); 338 #endif 339 return scoped_ptr<TrackedPreferenceValidationDelegate>(); 340 } 341 342 void SafeBrowsingService::RegisterDelayedAnalysisCallback( 343 const safe_browsing::DelayedAnalysisCallback& callback) { 344 #if defined(FULL_SAFE_BROWSING) 345 if (incident_service_) 346 incident_service_->RegisterDelayedAnalysisCallback(callback); 347 #endif 348 } 349 350 SafeBrowsingUIManager* SafeBrowsingService::CreateUIManager() { 351 return new SafeBrowsingUIManager(this); 352 } 353 354 SafeBrowsingDatabaseManager* SafeBrowsingService::CreateDatabaseManager() { 355 #if defined(FULL_SAFE_BROWSING) 356 return new SafeBrowsingDatabaseManager(this); 357 #else 358 return NULL; 359 #endif 360 } 361 362 void SafeBrowsingService::RegisterAllDelayedAnalysis() { 363 safe_browsing::RegisterBinaryIntegrityAnalysis(); 364 safe_browsing::RegisterBlacklistLoadAnalysis(); 365 } 366 367 void SafeBrowsingService::InitURLRequestContextOnIOThread( 368 net::URLRequestContextGetter* system_url_request_context_getter) { 369 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 370 DCHECK(!url_request_context_.get()); 371 372 scoped_refptr<net::CookieStore> cookie_store( 373 content::CreateCookieStore( 374 content::CookieStoreConfig( 375 CookieFilePath(), 376 content::CookieStoreConfig::EPHEMERAL_SESSION_COOKIES, 377 NULL, 378 NULL))); 379 380 url_request_context_.reset(new net::URLRequestContext); 381 // |system_url_request_context_getter| may be NULL during tests. 382 if (system_url_request_context_getter) { 383 url_request_context_->CopyFrom( 384 system_url_request_context_getter->GetURLRequestContext()); 385 } 386 url_request_context_->set_cookie_store(cookie_store.get()); 387 } 388 389 void SafeBrowsingService::DestroyURLRequestContextOnIOThread() { 390 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 391 392 url_request_context_->AssertNoURLRequests(); 393 394 // Need to do the CheckForLeaks on IOThread instead of in ShutDown where 395 // url_request_context_getter_ is cleared, since the URLRequestContextGetter 396 // will PostTask to IOTread to delete itself. 397 using base::debug::LeakTracker; 398 LeakTracker<SafeBrowsingURLRequestContextGetter>::CheckForLeaks(); 399 400 url_request_context_.reset(); 401 } 402 403 SafeBrowsingProtocolConfig SafeBrowsingService::GetProtocolConfig() const { 404 SafeBrowsingProtocolConfig config; 405 // On Windows, get the safe browsing client name from the browser 406 // distribution classes in installer util. These classes don't yet have 407 // an analog on non-Windows builds so just keep the name specified here. 408 #if defined(OS_WIN) 409 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); 410 config.client_name = dist->GetSafeBrowsingName(); 411 #else 412 #if defined(GOOGLE_CHROME_BUILD) 413 config.client_name = "googlechrome"; 414 #else 415 config.client_name = "chromium"; 416 #endif 417 418 // Mark client string to allow server to differentiate mobile. 419 #if defined(OS_ANDROID) 420 config.client_name.append("-a"); 421 #elif defined(OS_IOS) 422 config.client_name.append("-i"); 423 #endif 424 425 #endif // defined(OS_WIN) 426 CommandLine* cmdline = CommandLine::ForCurrentProcess(); 427 config.disable_auto_update = 428 cmdline->HasSwitch(switches::kSbDisableAutoUpdate) || 429 cmdline->HasSwitch(switches::kDisableBackgroundNetworking); 430 config.url_prefix = kSbDefaultURLPrefix; 431 config.backup_connect_error_url_prefix = kSbBackupConnectErrorURLPrefix; 432 config.backup_http_error_url_prefix = kSbBackupHttpErrorURLPrefix; 433 config.backup_network_error_url_prefix = kSbBackupNetworkErrorURLPrefix; 434 435 return config; 436 } 437 438 void SafeBrowsingService::StartOnIOThread( 439 net::URLRequestContextGetter* url_request_context_getter) { 440 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 441 if (enabled_) 442 return; 443 enabled_ = true; 444 445 SafeBrowsingProtocolConfig config = GetProtocolConfig(); 446 447 #if defined(FULL_SAFE_BROWSING) 448 DCHECK(database_manager_.get()); 449 database_manager_->StartOnIOThread(); 450 451 DCHECK(!protocol_manager_); 452 protocol_manager_ = SafeBrowsingProtocolManager::Create( 453 database_manager_.get(), url_request_context_getter, config); 454 protocol_manager_->Initialize(); 455 #endif 456 457 DCHECK(!ping_manager_); 458 ping_manager_ = SafeBrowsingPingManager::Create( 459 url_request_context_getter, config); 460 } 461 462 void SafeBrowsingService::StopOnIOThread(bool shutdown) { 463 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 464 465 #if defined(FULL_SAFE_BROWSING) 466 database_manager_->StopOnIOThread(shutdown); 467 #endif 468 ui_manager_->StopOnIOThread(shutdown); 469 470 if (enabled_) { 471 enabled_ = false; 472 473 #if defined(FULL_SAFE_BROWSING) 474 // This cancels all in-flight GetHash requests. Note that database_manager_ 475 // relies on the protocol_manager_ so if the latter is destroyed, the 476 // former must be stopped. 477 delete protocol_manager_; 478 protocol_manager_ = NULL; 479 #endif 480 delete ping_manager_; 481 ping_manager_ = NULL; 482 } 483 } 484 485 void SafeBrowsingService::Start() { 486 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 487 488 BrowserThread::PostTask( 489 BrowserThread::IO, FROM_HERE, 490 base::Bind(&SafeBrowsingService::StartOnIOThread, this, 491 url_request_context_getter_)); 492 } 493 494 void SafeBrowsingService::Stop(bool shutdown) { 495 BrowserThread::PostTask( 496 BrowserThread::IO, FROM_HERE, 497 base::Bind(&SafeBrowsingService::StopOnIOThread, this, shutdown)); 498 } 499 500 void SafeBrowsingService::Observe(int type, 501 const content::NotificationSource& source, 502 const content::NotificationDetails& details) { 503 switch (type) { 504 case chrome::NOTIFICATION_PROFILE_CREATED: { 505 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 506 Profile* profile = content::Source<Profile>(source).ptr(); 507 if (!profile->IsOffTheRecord()) 508 AddPrefService(profile->GetPrefs()); 509 break; 510 } 511 case chrome::NOTIFICATION_PROFILE_DESTROYED: { 512 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 513 Profile* profile = content::Source<Profile>(source).ptr(); 514 if (!profile->IsOffTheRecord()) 515 RemovePrefService(profile->GetPrefs()); 516 break; 517 } 518 default: 519 NOTREACHED(); 520 } 521 } 522 523 void SafeBrowsingService::AddPrefService(PrefService* pref_service) { 524 DCHECK(prefs_map_.find(pref_service) == prefs_map_.end()); 525 PrefChangeRegistrar* registrar = new PrefChangeRegistrar(); 526 registrar->Init(pref_service); 527 registrar->Add(prefs::kSafeBrowsingEnabled, 528 base::Bind(&SafeBrowsingService::RefreshState, 529 base::Unretained(this))); 530 prefs_map_[pref_service] = registrar; 531 RefreshState(); 532 } 533 534 void SafeBrowsingService::RemovePrefService(PrefService* pref_service) { 535 if (prefs_map_.find(pref_service) != prefs_map_.end()) { 536 delete prefs_map_[pref_service]; 537 prefs_map_.erase(pref_service); 538 RefreshState(); 539 } else { 540 NOTREACHED(); 541 } 542 } 543 544 void SafeBrowsingService::RefreshState() { 545 // Check if any profile requires the service to be active. 546 bool enable = false; 547 std::map<PrefService*, PrefChangeRegistrar*>::iterator iter; 548 for (iter = prefs_map_.begin(); iter != prefs_map_.end(); ++iter) { 549 if (iter->first->GetBoolean(prefs::kSafeBrowsingEnabled)) { 550 enable = true; 551 break; 552 } 553 } 554 555 if (enable) 556 Start(); 557 else 558 Stop(false); 559 560 #if defined(FULL_SAFE_BROWSING) 561 if (csd_service_) 562 csd_service_->SetEnabledAndRefreshState(enable); 563 if (download_service_) 564 download_service_->SetEnabled(enable); 565 #endif 566 } 567