Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / safe_browsing / safe_browsing_service.cc
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   net::URLRequestContext* GetURLRequestContext() override;
112   scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
113       const override;
114
115  protected:
116   ~SafeBrowsingURLRequestContextGetter() override;
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   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   incident_service_.reset();
284   download_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 void SafeBrowsingService::AddDownloadManager(
351     content::DownloadManager* download_manager) {
352 #if defined(FULL_SAFE_BROWSING)
353   if (incident_service_)
354     incident_service_->AddDownloadManager(download_manager);
355 #endif
356 }
357
358 SafeBrowsingUIManager* SafeBrowsingService::CreateUIManager() {
359   return new SafeBrowsingUIManager(this);
360 }
361
362 SafeBrowsingDatabaseManager* SafeBrowsingService::CreateDatabaseManager() {
363 #if defined(FULL_SAFE_BROWSING)
364   return new SafeBrowsingDatabaseManager(this);
365 #else
366   return NULL;
367 #endif
368 }
369
370 void SafeBrowsingService::RegisterAllDelayedAnalysis() {
371 #if defined(FULL_SAFE_BROWSING)
372   safe_browsing::RegisterBinaryIntegrityAnalysis();
373   safe_browsing::RegisterBlacklistLoadAnalysis();
374 #else
375   NOTREACHED();
376 #endif
377 }
378
379 void SafeBrowsingService::InitURLRequestContextOnIOThread(
380     net::URLRequestContextGetter* system_url_request_context_getter) {
381   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
382   DCHECK(!url_request_context_.get());
383
384   scoped_refptr<net::CookieStore> cookie_store(
385       content::CreateCookieStore(
386           content::CookieStoreConfig(
387               CookieFilePath(),
388               content::CookieStoreConfig::EPHEMERAL_SESSION_COOKIES,
389               NULL,
390               NULL)));
391
392   url_request_context_.reset(new net::URLRequestContext);
393   // |system_url_request_context_getter| may be NULL during tests.
394   if (system_url_request_context_getter) {
395     url_request_context_->CopyFrom(
396         system_url_request_context_getter->GetURLRequestContext());
397   }
398   url_request_context_->set_cookie_store(cookie_store.get());
399 }
400
401 void SafeBrowsingService::DestroyURLRequestContextOnIOThread() {
402   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
403
404   url_request_context_->AssertNoURLRequests();
405
406   // Need to do the CheckForLeaks on IOThread instead of in ShutDown where
407   // url_request_context_getter_ is cleared,  since the URLRequestContextGetter
408   // will PostTask to IOTread to delete itself.
409   using base::debug::LeakTracker;
410   LeakTracker<SafeBrowsingURLRequestContextGetter>::CheckForLeaks();
411
412   url_request_context_.reset();
413 }
414
415 SafeBrowsingProtocolConfig SafeBrowsingService::GetProtocolConfig() const {
416   SafeBrowsingProtocolConfig config;
417   // On Windows, get the safe browsing client name from the browser
418   // distribution classes in installer util. These classes don't yet have
419   // an analog on non-Windows builds so just keep the name specified here.
420 #if defined(OS_WIN)
421   BrowserDistribution* dist = BrowserDistribution::GetDistribution();
422   config.client_name = dist->GetSafeBrowsingName();
423 #else
424 #if defined(GOOGLE_CHROME_BUILD)
425   config.client_name = "googlechrome";
426 #else
427   config.client_name = "chromium";
428 #endif
429
430   // Mark client string to allow server to differentiate mobile.
431 #if defined(OS_ANDROID)
432   config.client_name.append("-a");
433 #elif defined(OS_IOS)
434   config.client_name.append("-i");
435 #endif
436
437 #endif  // defined(OS_WIN)
438   CommandLine* cmdline = CommandLine::ForCurrentProcess();
439   config.disable_auto_update =
440       cmdline->HasSwitch(switches::kSbDisableAutoUpdate) ||
441       cmdline->HasSwitch(switches::kDisableBackgroundNetworking);
442   config.url_prefix = kSbDefaultURLPrefix;
443   config.backup_connect_error_url_prefix = kSbBackupConnectErrorURLPrefix;
444   config.backup_http_error_url_prefix = kSbBackupHttpErrorURLPrefix;
445   config.backup_network_error_url_prefix = kSbBackupNetworkErrorURLPrefix;
446
447   return config;
448 }
449
450 void SafeBrowsingService::StartOnIOThread(
451     net::URLRequestContextGetter* url_request_context_getter) {
452   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
453   if (enabled_)
454     return;
455   enabled_ = true;
456
457   SafeBrowsingProtocolConfig config = GetProtocolConfig();
458
459 #if defined(FULL_SAFE_BROWSING)
460   DCHECK(database_manager_.get());
461   database_manager_->StartOnIOThread();
462
463   DCHECK(!protocol_manager_);
464   protocol_manager_ = SafeBrowsingProtocolManager::Create(
465       database_manager_.get(), url_request_context_getter, config);
466   protocol_manager_->Initialize();
467 #endif
468
469   DCHECK(!ping_manager_);
470   ping_manager_ = SafeBrowsingPingManager::Create(
471       url_request_context_getter, config);
472 }
473
474 void SafeBrowsingService::StopOnIOThread(bool shutdown) {
475   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
476
477 #if defined(FULL_SAFE_BROWSING)
478   database_manager_->StopOnIOThread(shutdown);
479 #endif
480   ui_manager_->StopOnIOThread(shutdown);
481
482   if (enabled_) {
483     enabled_ = false;
484
485 #if defined(FULL_SAFE_BROWSING)
486     // This cancels all in-flight GetHash requests. Note that database_manager_
487     // relies on the protocol_manager_ so if the latter is destroyed, the
488     // former must be stopped.
489     delete protocol_manager_;
490     protocol_manager_ = NULL;
491 #endif
492     delete ping_manager_;
493     ping_manager_ = NULL;
494   }
495 }
496
497 void SafeBrowsingService::Start() {
498   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
499
500   BrowserThread::PostTask(
501       BrowserThread::IO, FROM_HERE,
502       base::Bind(&SafeBrowsingService::StartOnIOThread, this,
503                  url_request_context_getter_));
504 }
505
506 void SafeBrowsingService::Stop(bool shutdown) {
507   BrowserThread::PostTask(
508       BrowserThread::IO, FROM_HERE,
509       base::Bind(&SafeBrowsingService::StopOnIOThread, this, shutdown));
510 }
511
512 void SafeBrowsingService::Observe(int type,
513                                   const content::NotificationSource& source,
514                                   const content::NotificationDetails& details) {
515   switch (type) {
516     case chrome::NOTIFICATION_PROFILE_CREATED: {
517       DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
518       Profile* profile = content::Source<Profile>(source).ptr();
519       if (!profile->IsOffTheRecord())
520         AddPrefService(profile->GetPrefs());
521       break;
522     }
523     case chrome::NOTIFICATION_PROFILE_DESTROYED: {
524       DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
525       Profile* profile = content::Source<Profile>(source).ptr();
526       if (!profile->IsOffTheRecord())
527         RemovePrefService(profile->GetPrefs());
528       break;
529     }
530     default:
531       NOTREACHED();
532   }
533 }
534
535 void SafeBrowsingService::AddPrefService(PrefService* pref_service) {
536   DCHECK(prefs_map_.find(pref_service) == prefs_map_.end());
537   PrefChangeRegistrar* registrar = new PrefChangeRegistrar();
538   registrar->Init(pref_service);
539   registrar->Add(prefs::kSafeBrowsingEnabled,
540                  base::Bind(&SafeBrowsingService::RefreshState,
541                             base::Unretained(this)));
542   prefs_map_[pref_service] = registrar;
543   RefreshState();
544 }
545
546 void SafeBrowsingService::RemovePrefService(PrefService* pref_service) {
547   if (prefs_map_.find(pref_service) != prefs_map_.end()) {
548     delete prefs_map_[pref_service];
549     prefs_map_.erase(pref_service);
550     RefreshState();
551   } else {
552     NOTREACHED();
553   }
554 }
555
556 void SafeBrowsingService::RefreshState() {
557   // Check if any profile requires the service to be active.
558   bool enable = false;
559   std::map<PrefService*, PrefChangeRegistrar*>::iterator iter;
560   for (iter = prefs_map_.begin(); iter != prefs_map_.end(); ++iter) {
561     if (iter->first->GetBoolean(prefs::kSafeBrowsingEnabled)) {
562       enable = true;
563       break;
564     }
565   }
566
567   if (enable)
568     Start();
569   else
570     Stop(false);
571
572 #if defined(FULL_SAFE_BROWSING)
573   if (csd_service_)
574     csd_service_->SetEnabledAndRefreshState(enable);
575   if (download_service_)
576     download_service_->SetEnabled(enable);
577 #endif
578 }