Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 // | 4 // |
| 5 // Implementation of the MalwareDetails class. | 5 // Implementation of the MalwareDetails class. |
| 6 | 6 |
| 7 #include "chrome/browser/safe_browsing/malware_details.h" | 7 #include "chrome/browser/safe_browsing/malware_details.h" |
| 8 | 8 |
| 9 #include "base/callback.h" | |
| 9 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| 11 #include "chrome/browser/net/chrome_url_request_context.h" | |
| 12 #include "chrome/browser/profiles/profile.h" | |
| 13 #include "chrome/browser/safe_browsing/malware_details_cache.h" | |
| 14 #include "chrome/browser/safe_browsing/report.pb.h" | |
| 10 #include "chrome/browser/safe_browsing/safe_browsing_service.h" | 15 #include "chrome/browser/safe_browsing/safe_browsing_service.h" |
| 11 #include "chrome/browser/safe_browsing/report.pb.h" | 16 #include "chrome/common/net/url_request_context_getter.h" |
| 12 #include "chrome/common/safebrowsing_messages.h" | 17 #include "chrome/common/safebrowsing_messages.h" |
| 13 #include "content/browser/browser_thread.h" | 18 #include "content/browser/browser_thread.h" |
| 14 #include "content/browser/renderer_host/render_view_host.h" | 19 #include "content/browser/renderer_host/render_view_host.h" |
| 15 #include "content/browser/tab_contents/navigation_entry.h" | 20 #include "content/browser/tab_contents/navigation_entry.h" |
| 16 #include "content/browser/tab_contents/tab_contents.h" | 21 #include "content/browser/tab_contents/tab_contents.h" |
| 22 #include "net/base/io_buffer.h" | |
| 23 #include "net/disk_cache/disk_cache.h" | |
| 17 | 24 |
| 18 using safe_browsing::ClientMalwareReportRequest; | 25 using safe_browsing::ClientMalwareReportRequest; |
| 19 | 26 |
| 20 // Keep in sync with KMaxNodes in renderer/safe_browsing/malware_dom_details | 27 // Keep in sync with KMaxNodes in renderer/safe_browsing/malware_dom_details |
| 21 static const uint32 kMaxDomNodes = 500; | 28 static const uint32 kMaxDomNodes = 500; |
| 22 | 29 |
| 23 // static | 30 // static |
| 24 MalwareDetailsFactory* MalwareDetails::factory_ = NULL; | 31 MalwareDetailsFactory* MalwareDetails::factory_ = NULL; |
| 25 | 32 |
| 26 // The default MalwareDetailsFactory. Global, made a singleton so we | 33 // The default MalwareDetailsFactory. Global, made a singleton so we |
| 27 // don't leak it. | 34 // don't leak it. |
| 28 class MalwareDetailsFactoryImpl | 35 class MalwareDetailsFactoryImpl |
| 29 : public MalwareDetailsFactory { | 36 : public MalwareDetailsFactory { |
| 30 public: | 37 public: |
| 31 MalwareDetails* CreateMalwareDetails( | 38 MalwareDetails* CreateMalwareDetails( |
| 39 SafeBrowsingService* sb_service, | |
| 32 TabContents* tab_contents, | 40 TabContents* tab_contents, |
| 33 const SafeBrowsingService::UnsafeResource& unsafe_resource) { | 41 const SafeBrowsingService::UnsafeResource& unsafe_resource) { |
| 34 return new MalwareDetails(tab_contents, unsafe_resource); | 42 return new MalwareDetails(sb_service, tab_contents, unsafe_resource); |
| 35 } | 43 } |
| 36 | 44 |
| 37 private: | 45 private: |
| 38 friend struct base::DefaultLazyInstanceTraits< | 46 friend struct base::DefaultLazyInstanceTraits< |
| 39 MalwareDetailsFactoryImpl>; | 47 MalwareDetailsFactoryImpl>; |
| 40 | 48 |
| 41 MalwareDetailsFactoryImpl() { } | 49 MalwareDetailsFactoryImpl() { } |
| 42 | 50 |
| 43 DISALLOW_COPY_AND_ASSIGN(MalwareDetailsFactoryImpl); | 51 DISALLOW_COPY_AND_ASSIGN(MalwareDetailsFactoryImpl); |
| 44 }; | 52 }; |
| 45 | 53 |
| 46 static base::LazyInstance<MalwareDetailsFactoryImpl> | 54 static base::LazyInstance<MalwareDetailsFactoryImpl> |
| 47 g_malware_details_factory_impl(base::LINKER_INITIALIZED); | 55 g_malware_details_factory_impl(base::LINKER_INITIALIZED); |
| 48 | 56 |
| 49 // Create a MalwareDetails for the given tab. | 57 // Create a MalwareDetails for the given tab. |
| 50 /* static */ | 58 /* static */ |
| 51 MalwareDetails* MalwareDetails::NewMalwareDetails( | 59 MalwareDetails* MalwareDetails::NewMalwareDetails( |
| 60 SafeBrowsingService* sb_service, | |
| 52 TabContents* tab_contents, | 61 TabContents* tab_contents, |
| 53 const SafeBrowsingService::UnsafeResource& resource) { | 62 const SafeBrowsingService::UnsafeResource& resource) { |
| 54 // Set up the factory if this has not been done already (tests do that | 63 // Set up the factory if this has not been done already (tests do that |
| 55 // before this method is called). | 64 // before this method is called). |
| 56 if (!factory_) | 65 if (!factory_) |
| 57 factory_ = g_malware_details_factory_impl.Pointer(); | 66 factory_ = g_malware_details_factory_impl.Pointer(); |
| 58 return factory_->CreateMalwareDetails(tab_contents, resource); | 67 return factory_->CreateMalwareDetails(sb_service, tab_contents, resource); |
| 59 } | 68 } |
| 60 | 69 |
| 61 // Create a MalwareDetails for the given tab. Runs in the UI thread. | 70 // Create a MalwareDetails for the given tab. Runs in the UI thread. |
| 62 MalwareDetails::MalwareDetails( | 71 MalwareDetails::MalwareDetails( |
| 72 SafeBrowsingService* sb_service, | |
| 63 TabContents* tab_contents, | 73 TabContents* tab_contents, |
| 64 const SafeBrowsingService::UnsafeResource& resource) | 74 const SafeBrowsingService::UnsafeResource& resource) |
| 65 : TabContentsObserver(tab_contents), | 75 : TabContentsObserver(tab_contents), |
| 66 resource_(resource) { | 76 request_context_getter_(tab_contents->profile()->GetRequestContext()), |
| 77 sb_service_(sb_service), | |
| 78 resource_(resource), | |
| 79 cache_collector_(new MalwareDetailsCacheCollector) { | |
| 67 StartCollection(); | 80 StartCollection(); |
| 68 } | 81 } |
| 69 | 82 |
| 70 MalwareDetails::~MalwareDetails() {} | 83 MalwareDetails::~MalwareDetails() { |
| 84 } | |
| 71 | 85 |
| 72 bool MalwareDetails::OnMessageReceived(const IPC::Message& message) { | 86 bool MalwareDetails::OnMessageReceived(const IPC::Message& message) { |
| 73 bool handled = true; | 87 bool handled = true; |
| 74 IPC_BEGIN_MESSAGE_MAP(MalwareDetails, message) | 88 IPC_BEGIN_MESSAGE_MAP(MalwareDetails, message) |
| 75 IPC_MESSAGE_HANDLER(SafeBrowsingHostMsg_MalwareDOMDetails, | 89 IPC_MESSAGE_HANDLER(SafeBrowsingHostMsg_MalwareDOMDetails, |
| 76 OnReceivedMalwareDOMDetails) | 90 OnReceivedMalwareDOMDetails) |
| 77 IPC_MESSAGE_UNHANDLED(handled = false) | 91 IPC_MESSAGE_UNHANDLED(handled = false) |
| 78 IPC_END_MESSAGE_MAP() | 92 IPC_END_MESSAGE_MAP() |
| 79 return handled; | 93 return handled; |
| 80 } | 94 } |
| 81 | 95 |
| 82 bool MalwareDetails::IsPublicUrl(const GURL& url) const { | 96 bool MalwareDetails::IsPublicUrl(const GURL& url) const { |
| 83 return url.SchemeIs("http"); // TODO(panayiotis): also skip internal urls. | 97 return url.SchemeIs("http"); // TODO(panayiotis): also skip internal urls. |
| 84 } | 98 } |
| 85 | 99 |
| 86 // Looks for a Resource for the given url in resources_. If found, it | 100 // Looks for a Resource for the given url in resources_. If found, it |
| 87 // updates |resource|. Otherwise, it creates a new message, adds it to | 101 // updates |resource|. Otherwise, it creates a new message, adds it to |
| 88 // resources_ and updates |resource| to point to it. | 102 // resources_ and updates |resource| to point to it. |
| 89 ClientMalwareReportRequest::Resource* MalwareDetails::FindOrCreateResource( | 103 ClientMalwareReportRequest::Resource* MalwareDetails::FindOrCreateResource( |
| 90 const GURL& url) { | 104 const GURL& url) { |
| 91 ResourceMap::iterator it = resources_.find(url.spec()); | 105 safe_browsing::ResourceMap::iterator it = resources_.find(url.spec()); |
| 92 if (it != resources_.end()) { | 106 if (it != resources_.end()) { |
| 93 return it->second.get(); | 107 return it->second.get(); |
| 94 } | 108 } |
| 95 | 109 |
| 96 // Create the resource for |url|. | 110 // Create the resource for |url|. |
| 97 int id = resources_.size(); | 111 int id = resources_.size(); |
| 98 linked_ptr<ClientMalwareReportRequest::Resource> new_resource( | 112 linked_ptr<ClientMalwareReportRequest::Resource> new_resource( |
| 99 new ClientMalwareReportRequest::Resource()); | 113 new ClientMalwareReportRequest::Resource()); |
| 100 new_resource->set_url(url.spec()); | 114 new_resource->set_url(url.spec()); |
| 101 new_resource->set_id(id); | 115 new_resource->set_id(id); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 200 // of our data structures (eg GetSerializedReport). | 214 // of our data structures (eg GetSerializedReport). |
| 201 BrowserThread::PostTask( | 215 BrowserThread::PostTask( |
| 202 BrowserThread::IO, FROM_HERE, | 216 BrowserThread::IO, FROM_HERE, |
| 203 NewRunnableMethod( | 217 NewRunnableMethod( |
| 204 this, &MalwareDetails::AddDOMDetails, params)); | 218 this, &MalwareDetails::AddDOMDetails, params)); |
| 205 } | 219 } |
| 206 | 220 |
| 207 void MalwareDetails::AddDOMDetails( | 221 void MalwareDetails::AddDOMDetails( |
| 208 const std::vector<SafeBrowsingHostMsg_MalwareDOMDetails_Node>& params) { | 222 const std::vector<SafeBrowsingHostMsg_MalwareDOMDetails_Node>& params) { |
| 209 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 223 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 224 DVLOG(1) << "Nodes from the DOM: " << params.size(); | |
| 225 | |
| 226 // If we have already started collecting data from the HTTP cache, don't | |
| 227 // modify our state. | |
| 228 if (cache_collector_->InProgress()) | |
| 229 return; | |
| 230 | |
| 210 // Add the urls from the DOM to |resources_|. The renderer could be | 231 // Add the urls from the DOM to |resources_|. The renderer could be |
| 211 // sending bogus messages, so limit the number of nodes we accept. | 232 // sending bogus messages, so limit the number of nodes we accept. |
| 212 DVLOG(1) << "Nodes from the DOM: " << params.size(); | |
| 213 for (uint32 i = 0; i < params.size() && i < kMaxDomNodes; ++i) { | 233 for (uint32 i = 0; i < params.size() && i < kMaxDomNodes; ++i) { |
| 214 SafeBrowsingHostMsg_MalwareDOMDetails_Node node = params[i]; | 234 SafeBrowsingHostMsg_MalwareDOMDetails_Node node = params[i]; |
| 215 DVLOG(1) << node.url << ", " << node.tag_name << ", " << node.parent; | 235 DVLOG(1) << node.url << ", " << node.tag_name << ", " << node.parent; |
| 216 AddUrl(node.url, node.parent, node.tag_name, &(node.children)); | 236 AddUrl(node.url, node.parent, node.tag_name, &(node.children)); |
| 217 } | 237 } |
| 218 } | 238 } |
| 219 | 239 |
| 220 // Called from the SB Service on the IO thread, after the user has | 240 // Called from the SB Service on the IO thread, after the user has |
| 221 // closed the tab, or clicked proceed or goback. Since the user needs | 241 // closed the tab, or clicked proceed or goback. Since the user needs |
| 222 // to take an action, we expect this to be called after | 242 // to take an action, we expect this to be called after |
| 223 // OnReceivedMalwareDOMDetails in most cases. If not, we don't include | 243 // OnReceivedMalwareDOMDetails in most cases. If not, we don't include |
| 224 // the DOM data in our report. | 244 // the DOM data in our report. |
| 225 const std::string* MalwareDetails::GetSerializedReport() { | 245 void MalwareDetails::FinishCollection() { |
| 226 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 246 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 227 // The |report_| protocol buffer is now generated: We add all the | 247 |
| 228 // urls in our |resources_| maps. | 248 cache_collector_->StartCacheCollection( |
| 229 for (ResourceMap::const_iterator it = resources_.begin(); | 249 request_context_getter_, |
| 250 &resources_, | |
| 251 &cache_result_, | |
| 252 NewRunnableMethod(this, &MalwareDetails::OnCacheCollectionReady)); | |
| 253 } | |
| 254 | |
| 255 void MalwareDetails::OnCacheCollectionReady() { | |
| 256 DVLOG(1) << "OnCacheCollectionReady."; | |
| 257 // Add all the urls in our |resources_| maps to the |report_| protocol buffer. | |
| 258 for (safe_browsing::ResourceMap::const_iterator it = resources_.begin(); | |
| 230 it != resources_.end(); it++) { | 259 it != resources_.end(); it++) { |
| 231 ClientMalwareReportRequest::Resource* pb_resource = | 260 ClientMalwareReportRequest::Resource* pb_resource = |
| 232 report_->add_resources(); | 261 report_->add_resources(); |
| 233 pb_resource->CopyFrom(*(it->second)); | 262 pb_resource->CopyFrom(*(it->second)); |
| 234 } | 263 } |
| 235 | 264 |
| 236 scoped_ptr<std::string> request_data(new std::string()); | 265 report_->set_complete(cache_result_ == net::OK); |
| 237 if (!report_->SerializeToString(request_data.get())) { | 266 |
| 267 // Send the report, using the SafeBrowsingService. | |
| 268 std::string serialized; | |
|
noelutz
2011/04/06 20:34:19
can you explain why you're serializing here instea
panayiotis
2011/04/07 20:08:32
This was Lei's suggestion, it makes it simpler tha
| |
| 269 if (!report_->SerializeToString(&serialized)) { | |
| 238 DLOG(ERROR) << "Unable to serialize the malware report."; | 270 DLOG(ERROR) << "Unable to serialize the malware report."; |
|
noelutz
2011/04/06 20:34:19
Do you want to return here?
panayiotis
2011/04/07 20:08:32
Done.
| |
| 239 } | 271 } |
| 240 | 272 |
| 241 return request_data.release(); | 273 sb_service_->SendSerializedMalwareDetails(serialized); |
| 242 } | 274 } |
| OLD | NEW |