1// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_SAFE_BROWSING_MALWARE_DETAILS_H_
6#define CHROME_BROWSER_SAFE_BROWSING_MALWARE_DETAILS_H_
7
8// A class that encapsulates the detailed malware reports sent when
9// users opt-in to do so from the malware warning page.
10
11// An instance of this class is generated when a malware warning page
12// is shown (SafeBrowsingBlockingPage).
13
14#include <string>
15#include <vector>
16
17#include "base/containers/hash_tables.h"
18#include "base/gtest_prod_util.h"
19#include "base/memory/linked_ptr.h"
20#include "base/memory/ref_counted.h"
21#include "base/memory/scoped_ptr.h"
22#include "chrome/browser/safe_browsing/report.pb.h"
23#include "chrome/browser/safe_browsing/ui_manager.h"
24#include "content/public/browser/web_contents_observer.h"
25#include "net/base/completion_callback.h"
26
27namespace net {
28class URLRequestContextGetter;
29}
30
31class MalwareDetailsCacheCollector;
32class MalwareDetailsRedirectsCollector;
33class MalwareDetailsFactory;
34class Profile;
35struct SafeBrowsingHostMsg_MalwareDOMDetails_Node;
36
37namespace safe_browsing {
38// Maps a URL to its Resource.
39typedef base::hash_map<
40  std::string,
41  linked_ptr<safe_browsing::ClientMalwareReportRequest::Resource> > ResourceMap;
42}
43
44class MalwareDetails : public base::RefCountedThreadSafe<MalwareDetails>,
45                       public content::WebContentsObserver {
46 public:
47  typedef SafeBrowsingUIManager::UnsafeResource UnsafeResource;
48
49  // Constructs a new MalwareDetails instance, using the factory.
50  static MalwareDetails* NewMalwareDetails(
51      SafeBrowsingUIManager* ui_manager,
52      content::WebContents* web_contents,
53      const UnsafeResource& resource);
54
55  // Makes the passed |factory| the factory used to instanciate
56  // SafeBrowsingBlockingPage objects. Useful for tests.
57  static void RegisterFactory(MalwareDetailsFactory* factory) {
58    factory_ = factory;
59  }
60
61  // The SafeBrowsingBlockingPage calls this from the IO thread when
62  // the user is leaving the blocking page and has opted-in to sending
63  // the report. We start the redirection urls collection from history service
64  // in UI thread; then do cache collection back in IO thread.
65  // When we are done, we send the report.
66  void FinishCollection();
67
68  void OnCacheCollectionReady();
69
70  void OnRedirectionCollectionReady();
71
72  // content::WebContentsObserver implementation.
73  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
74
75 protected:
76  friend class MalwareDetailsFactoryImpl;
77
78  MalwareDetails(SafeBrowsingUIManager* ui_manager,
79                 content::WebContents* web_contents,
80                 const UnsafeResource& resource);
81
82  virtual ~MalwareDetails();
83
84  // Called on the IO thread with the DOM details.
85  virtual void AddDOMDetails(
86      const std::vector<SafeBrowsingHostMsg_MalwareDOMDetails_Node>& params);
87
88  Profile* profile_;
89
90  // The report protocol buffer.
91  scoped_ptr<safe_browsing::ClientMalwareReportRequest> report_;
92
93  // Used to get a pointer to the HTTP cache.
94  scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
95
96 private:
97  friend class base::RefCountedThreadSafe<MalwareDetails>;
98
99  // Starts the collection of the report.
100  void StartCollection();
101
102  // Whether the url is "public" so we can add it to the report.
103  bool IsPublicUrl(const GURL& url) const;
104
105  // Finds an existing Resource for the given url, or creates a new
106  // one if not found, and adds it to |resources_|. Returns the
107  // found/created resource.
108  safe_browsing::ClientMalwareReportRequest::Resource* FindOrCreateResource(
109      const GURL& url);
110
111  // Adds a Resource to resources_ with the given parent-child
112  // relationship. |parent| and |tagname| can be empty, |children| can be NULL.
113  void AddUrl(const GURL& url,
114              const GURL& parent,
115              const std::string& tagname,
116              const std::vector<GURL>* children);
117
118  // Message handler.
119  void OnReceivedMalwareDOMDetails(
120      const std::vector<SafeBrowsingHostMsg_MalwareDOMDetails_Node>& params);
121
122  void AddRedirectUrlList(const std::vector<GURL>& urls);
123
124  scoped_refptr<SafeBrowsingUIManager> ui_manager_;
125
126  const UnsafeResource resource_;
127
128  // For every Url we collect we create a Resource message. We keep
129  // them in a map so we can avoid duplicates.
130  safe_browsing::ResourceMap resources_;
131
132  // Result from the cache extractor.
133  bool cache_result_;
134
135  // The factory used to instanciate SafeBrowsingBlockingPage objects.
136  // Usefull for tests, so they can provide their own implementation of
137  // SafeBrowsingBlockingPage.
138  static MalwareDetailsFactory* factory_;
139
140  // Used to collect details from the HTTP Cache.
141  scoped_refptr<MalwareDetailsCacheCollector> cache_collector_;
142
143  // Used to collect redirect urls from the history service
144  scoped_refptr<MalwareDetailsRedirectsCollector> redirects_collector_;
145
146  FRIEND_TEST_ALL_PREFIXES(MalwareDetailsTest, MalwareDOMDetails);
147  FRIEND_TEST_ALL_PREFIXES(MalwareDetailsTest, HTTPCache);
148  FRIEND_TEST_ALL_PREFIXES(MalwareDetailsTest, HTTPCacheNoEntries);
149  FRIEND_TEST_ALL_PREFIXES(MalwareDetailsTest, HistoryServiceUrls);
150
151  DISALLOW_COPY_AND_ASSIGN(MalwareDetails);
152};
153
154// Factory for creating MalwareDetails.  Useful for tests.
155class MalwareDetailsFactory {
156 public:
157  virtual ~MalwareDetailsFactory() { }
158
159  virtual MalwareDetails* CreateMalwareDetails(
160      SafeBrowsingUIManager* ui_manager,
161      content::WebContents* web_contents,
162      const SafeBrowsingUIManager::UnsafeResource& unsafe_resource) = 0;
163};
164
165#endif  // CHROME_BROWSER_SAFE_BROWSING_MALWARE_DETAILS_H_
166