15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 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)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/safe_browsing/safe_browsing_service.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <vector>
8f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/leak_tracker.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_change_registrar.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/prefs/tracked/tracked_preference_validation_delegate.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/safe_browsing/client_side_detection_service.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/safe_browsing/database_manager.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/safe_browsing/download_protection_service.h"
306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer.h"
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/safe_browsing/incident_reporting/blacklist_load_analyzer.h"
326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/safe_browsing/malware_details.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/safe_browsing/ping_manager.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/safe_browsing/protocol_manager.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/safe_browsing/safe_browsing_database.h"
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/safe_browsing/ui_manager.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_constants.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "components/metrics/metrics_service.h"
4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "components/startup_metric_utils/startup_metric_utils.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/cookie_crypto_delegate.h"
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/cookie_store_factory.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/cookies/cookie_monster.h"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h"
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/browser_distribution.h"
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if defined(OS_ANDROID)
5846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include <string>
5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/metrics/field_trial.h"
6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif
6146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Filename suffix for the cookie database.
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const base::FilePath::CharType kCookiesFile[] = FILE_PATH_LITERAL(" Cookies");
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The default URL prefix where browser fetches chunk updates, hashes,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and reports safe browsing hits and malware details.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kSbDefaultURLPrefix =
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "https://safebrowsing.google.com/safebrowsing";
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The backup URL prefix used when there are issues establishing a connection
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// with the server at the primary URL.
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char* const kSbBackupConnectErrorURLPrefix =
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "https://alt1-safebrowsing.google.com/safebrowsing";
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The backup URL prefix used when there are HTTP-specific issues with the
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// server at the primary URL.
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char* const kSbBackupHttpErrorURLPrefix =
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "https://alt2-safebrowsing.google.com/safebrowsing";
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The backup URL prefix used when there are local network specific issues.
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char* const kSbBackupNetworkErrorURLPrefix =
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "https://alt3-safebrowsing.google.com/safebrowsing";
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath CookieFilePath() {
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base::FilePath(
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SafeBrowsingService::GetBaseFilename().value() + kCookiesFile);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(FULL_SAFE_BROWSING)
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Returns true if the incident reporting service is enabled via a field trial.
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool IsIncidentReportingServiceEnabled() {
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const std::string group_name = base::FieldTrialList::FindFullName(
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "SafeBrowsingIncidentReportingService");
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return group_name == "Enabled";
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif  // defined(FULL_SAFE_BROWSING)
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SafeBrowsingURLRequestContextGetter
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public net::URLRequestContextGetter {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit SafeBrowsingURLRequestContextGetter(
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SafeBrowsingService* sb_service_);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Implementation for net::UrlRequestContextGetter.
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual scoped_refptr<base::SingleThreadTaskRunner>
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetNetworkTaskRunner() const OVERRIDE;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SafeBrowsingURLRequestContextGetter();
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SafeBrowsingService* const sb_service_;  // Owned by BrowserProcess.
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::debug::LeakTracker<SafeBrowsingURLRequestContextGetter> leak_tracker_;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SafeBrowsingURLRequestContextGetter::SafeBrowsingURLRequestContextGetter(
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SafeBrowsingService* sb_service)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : sb_service_(sb_service),
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      network_task_runner_(
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SafeBrowsingURLRequestContextGetter::~SafeBrowsingURLRequestContextGetter() {}
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)net::URLRequestContext*
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SafeBrowsingURLRequestContextGetter::GetURLRequestContext() {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(sb_service_->url_request_context_.get());
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return sb_service_->url_request_context_.get();
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<base::SingleThreadTaskRunner>
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SafeBrowsingURLRequestContextGetter::GetNetworkTaskRunner() const {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return network_task_runner_;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SafeBrowsingServiceFactory* SafeBrowsingService::factory_ = NULL;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The default SafeBrowsingServiceFactory.  Global, made a singleton so we
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// don't leak it.
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SafeBrowsingServiceFactoryImpl : public SafeBrowsingServiceFactory {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual SafeBrowsingService* CreateSafeBrowsingService() OVERRIDE {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return new SafeBrowsingService();
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend struct base::DefaultLazyInstanceTraits<SafeBrowsingServiceFactoryImpl>;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SafeBrowsingServiceFactoryImpl() { }
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceFactoryImpl);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static base::LazyInstance<SafeBrowsingServiceFactoryImpl>::Leaky
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_safe_browsing_service_factory_impl = LAZY_INSTANCE_INITIALIZER;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath SafeBrowsingService::GetCookieFilePathForTesting() {
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return CookieFilePath();
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath SafeBrowsingService::GetBaseFilename() {
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath path;
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool result = PathService::Get(chrome::DIR_USER_DATA, &path);
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(result);
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return path.Append(chrome::kSafeBrowsingBaseFilename);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SafeBrowsingService* SafeBrowsingService::CreateSafeBrowsingService() {
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!factory_)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    factory_ = g_safe_browsing_service_factory_impl.Pointer();
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return factory_->CreateSafeBrowsingService();
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
190f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(OS_ANDROID) && defined(FULL_SAFE_BROWSING)
19146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// static
19246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool SafeBrowsingService::IsEnabledByFieldTrial() {
19346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  const std::string experiment_name =
19446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::FieldTrialList::FindFullName("SafeBrowsingAndroid");
19546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return experiment_name == "Enabled";
19646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
19746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif
19846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SafeBrowsingService::SafeBrowsingService()
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : protocol_manager_(NULL),
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ping_manager_(NULL),
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      enabled_(false) {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SafeBrowsingService::~SafeBrowsingService() {
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should have already been shut down. If we're still enabled, then the
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // database isn't going to be closed properly, which could lead to corruption.
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!enabled_);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SafeBrowsingService::Initialize() {
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  startup_metric_utils::ScopedSlowStartupUMA
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scoped_timer("Startup.SlowStartupSafeBrowsingServiceInitialize");
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  url_request_context_getter_ =
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new SafeBrowsingURLRequestContextGetter(this);
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui_manager_ = CreateUIManager();
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  database_manager_ = CreateDatabaseManager();
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::IO, FROM_HERE,
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &SafeBrowsingService::InitURLRequestContextOnIOThread, this,
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          make_scoped_refptr(g_browser_process->system_request_context())));
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(FULL_SAFE_BROWSING)
229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if !defined(OS_ANDROID)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!CommandLine::ForCurrentProcess()->HasSwitch(
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          switches::kDisableClientSidePhishingDetection)) {
232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    csd_service_.reset(safe_browsing::ClientSideDetectionService::Create(
233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        url_request_context_getter_.get()));
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  download_service_.reset(new safe_browsing::DownloadProtectionService(
236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      this, url_request_context_getter_.get()));
237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif
238f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (IsIncidentReportingServiceEnabled()) {
240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    incident_service_.reset(new safe_browsing::IncidentReportingService(
241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        this, url_request_context_getter_));
242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Track the safe browsing preference of existing profiles.
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The SafeBrowsingService will be started if any existing profile has the
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // preference enabled. It will also listen for updates to the preferences.
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProfileManager* profile_manager = g_browser_process->profile_manager();
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (profile_manager) {
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<Profile*> profiles = profile_manager->GetLoadedProfiles();
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < profiles.size(); ++i) {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (profiles[i]->IsOffTheRecord())
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AddPrefService(profiles[i]->GetPrefs());
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Track profile creation and destruction.
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED,
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       content::NotificationService::AllSources());
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       content::NotificationService::AllSources());
2636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#if defined(FULL_SAFE_BROWSING)
2656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Register all the delayed analysis to the incident reporting service.
2666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  RegisterAllDelayedAnalysis();
2676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#endif
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SafeBrowsingService::ShutDown() {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Deletes the PrefChangeRegistrars, whose dtors also unregister |this| as an
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // observer of the preferences.
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STLDeleteValues(&prefs_map_);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove Profile creation/destruction observers.
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs_registrar_.RemoveAll();
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Stop(true);
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The IO thread is going away, so make sure the ClientSideDetectionService
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // dtor executes now since it may call the dtor of URLFetcher which relies
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on it.
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  csd_service_.reset();
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  download_service_.reset();
284f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  incident_service_.reset();
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  url_request_context_getter_ = NULL;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostNonNestableTask(
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::IO, FROM_HERE,
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&SafeBrowsingService::DestroyURLRequestContextOnIOThread,
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 this));
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Binhash verification is only enabled for UMA users for now.
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SafeBrowsingService::DownloadBinHashNeeded() const {
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(FULL_SAFE_BROWSING)
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (database_manager_->download_protection_enabled() &&
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          ui_manager_->CanReportStats()) ||
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (download_protection_service() &&
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       download_protection_service()->enabled());
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)net::URLRequestContextGetter* SafeBrowsingService::url_request_context() {
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return url_request_context_getter_.get();
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const scoped_refptr<SafeBrowsingUIManager>&
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SafeBrowsingService::ui_manager() const {
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ui_manager_;
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const scoped_refptr<SafeBrowsingDatabaseManager>&
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SafeBrowsingService::database_manager() const {
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return database_manager_;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SafeBrowsingProtocolManager* SafeBrowsingService::protocol_manager() const {
3234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return protocol_manager_;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SafeBrowsingPingManager* SafeBrowsingService::ping_manager() const {
3284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ping_manager_;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)scoped_ptr<TrackedPreferenceValidationDelegate>
3336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)SafeBrowsingService::CreatePreferenceValidationDelegate(
3346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    Profile* profile) const {
335f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(FULL_SAFE_BROWSING)
336f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (incident_service_)
3376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return incident_service_->CreatePreferenceValidationDelegate(profile);
338f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif
339f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return scoped_ptr<TrackedPreferenceValidationDelegate>();
340f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
341f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
3425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SafeBrowsingService::RegisterDelayedAnalysisCallback(
3435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const safe_browsing::DelayedAnalysisCallback& callback) {
3445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(FULL_SAFE_BROWSING)
3455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (incident_service_)
3465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    incident_service_->RegisterDelayedAnalysisCallback(callback);
3475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif
3485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SafeBrowsingUIManager* SafeBrowsingService::CreateUIManager() {
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return new SafeBrowsingUIManager(this);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SafeBrowsingDatabaseManager* SafeBrowsingService::CreateDatabaseManager() {
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(FULL_SAFE_BROWSING)
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return new SafeBrowsingDatabaseManager(this);
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return NULL;
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void SafeBrowsingService::RegisterAllDelayedAnalysis() {
3636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  safe_browsing::RegisterBinaryIntegrityAnalysis();
3641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  safe_browsing::RegisterBlacklistLoadAnalysis();
3656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
3666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SafeBrowsingService::InitURLRequestContextOnIOThread(
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::URLRequestContextGetter* system_url_request_context_getter) {
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!url_request_context_.get());
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<net::CookieStore> cookie_store(
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      content::CreateCookieStore(
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          content::CookieStoreConfig(
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              CookieFilePath(),
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              content::CookieStoreConfig::EPHEMERAL_SESSION_COOKIES,
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              NULL,
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              NULL)));
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  url_request_context_.reset(new net::URLRequestContext);
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |system_url_request_context_getter| may be NULL during tests.
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (system_url_request_context_getter) {
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_request_context_->CopyFrom(
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        system_url_request_context_getter->GetURLRequestContext());
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
386868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  url_request_context_->set_cookie_store(cookie_store.get());
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SafeBrowsingService::DestroyURLRequestContextOnIOThread() {
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  url_request_context_->AssertNoURLRequests();
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Need to do the CheckForLeaks on IOThread instead of in ShutDown where
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // url_request_context_getter_ is cleared,  since the URLRequestContextGetter
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will PostTask to IOTread to delete itself.
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  using base::debug::LeakTracker;
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LeakTracker<SafeBrowsingURLRequestContextGetter>::CheckForLeaks();
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  url_request_context_.reset();
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SafeBrowsingProtocolConfig SafeBrowsingService::GetProtocolConfig() const {
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SafeBrowsingProtocolConfig config;
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // On Windows, get the safe browsing client name from the browser
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // distribution classes in installer util. These classes don't yet have
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // an analog on non-Windows builds so just keep the name specified here.
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserDistribution* dist = BrowserDistribution::GetDistribution();
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.client_name = dist->GetSafeBrowsingName();
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(GOOGLE_CHROME_BUILD)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.client_name = "googlechrome";
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.client_name = "chromium";
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
417f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
418f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Mark client string to allow server to differentiate mobile.
419f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(OS_ANDROID)
420f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  config.client_name.append("-a");
421f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#elif defined(OS_IOS)
422f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  config.client_name.append("-i");
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
424f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
425f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif  // defined(OS_WIN)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandLine* cmdline = CommandLine::ForCurrentProcess();
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.disable_auto_update =
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cmdline->HasSwitch(switches::kSbDisableAutoUpdate) ||
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cmdline->HasSwitch(switches::kDisableBackgroundNetworking);
430a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  config.url_prefix = kSbDefaultURLPrefix;
431a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  config.backup_connect_error_url_prefix = kSbBackupConnectErrorURLPrefix;
432a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  config.backup_http_error_url_prefix = kSbBackupHttpErrorURLPrefix;
433a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  config.backup_network_error_url_prefix = kSbBackupNetworkErrorURLPrefix;
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return config;
4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SafeBrowsingService::StartOnIOThread(
4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    net::URLRequestContextGetter* url_request_context_getter) {
4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (enabled_)
4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  enabled_ = true;
4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SafeBrowsingProtocolConfig config = GetProtocolConfig();
4465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(FULL_SAFE_BROWSING)
448868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(database_manager_.get());
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  database_manager_->StartOnIOThread();
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!protocol_manager_);
452868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  protocol_manager_ = SafeBrowsingProtocolManager::Create(
4534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      database_manager_.get(), url_request_context_getter, config);
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protocol_manager_->Initialize();
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!ping_manager_);
458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ping_manager_ = SafeBrowsingPingManager::Create(
4594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      url_request_context_getter, config);
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SafeBrowsingService::StopOnIOThread(bool shutdown) {
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(FULL_SAFE_BROWSING)
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  database_manager_->StopOnIOThread(shutdown);
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui_manager_->StopOnIOThread(shutdown);
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (enabled_) {
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    enabled_ = false;
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(FULL_SAFE_BROWSING)
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // This cancels all in-flight GetHash requests. Note that database_manager_
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // relies on the protocol_manager_ so if the latter is destroyed, the
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // former must be stopped.
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete protocol_manager_;
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    protocol_manager_ = NULL;
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete ping_manager_;
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ping_manager_ = NULL;
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SafeBrowsingService::Start() {
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::IO, FROM_HERE,
4904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::Bind(&SafeBrowsingService::StartOnIOThread, this,
4914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                 url_request_context_getter_));
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SafeBrowsingService::Stop(bool shutdown) {
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::IO, FROM_HERE,
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&SafeBrowsingService::StopOnIOThread, this, shutdown));
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SafeBrowsingService::Observe(int type,
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const content::NotificationSource& source,
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const content::NotificationDetails& details) {
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (type) {
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case chrome::NOTIFICATION_PROFILE_CREATED: {
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Profile* profile = content::Source<Profile>(source).ptr();
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!profile->IsOffTheRecord())
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AddPrefService(profile->GetPrefs());
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case chrome::NOTIFICATION_PROFILE_DESTROYED: {
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Profile* profile = content::Source<Profile>(source).ptr();
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!profile->IsOffTheRecord())
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        RemovePrefService(profile->GetPrefs());
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SafeBrowsingService::AddPrefService(PrefService* pref_service) {
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(prefs_map_.find(pref_service) == prefs_map_.end());
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrefChangeRegistrar* registrar = new PrefChangeRegistrar();
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar->Init(pref_service);
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  registrar->Add(prefs::kSafeBrowsingEnabled,
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Bind(&SafeBrowsingService::RefreshState,
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            base::Unretained(this)));
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  prefs_map_[pref_service] = registrar;
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RefreshState();
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SafeBrowsingService::RemovePrefService(PrefService* pref_service) {
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (prefs_map_.find(pref_service) != prefs_map_.end()) {
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete prefs_map_[pref_service];
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    prefs_map_.erase(pref_service);
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RefreshState();
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SafeBrowsingService::RefreshState() {
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check if any profile requires the service to be active.
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool enable = false;
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<PrefService*, PrefChangeRegistrar*>::iterator iter;
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (iter = prefs_map_.begin(); iter != prefs_map_.end(); ++iter) {
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (iter->first->GetBoolean(prefs::kSafeBrowsingEnabled)) {
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      enable = true;
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (enable)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Start();
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Stop(false);
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(FULL_SAFE_BROWSING)
561f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (csd_service_)
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    csd_service_->SetEnabledAndRefreshState(enable);
563f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (download_service_)
564a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    download_service_->SetEnabled(enable);
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
567