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