OLD | NEW |
---|---|
1 // Copyright (c) 2011 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 #include "chrome/browser/safe_browsing/download_protection_service.h" | 5 #include "chrome/browser/safe_browsing/download_protection_service.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
11 #include "base/string_util.h" | |
11 #include "chrome/browser/safe_browsing/safe_browsing_service.h" | 12 #include "chrome/browser/safe_browsing/safe_browsing_service.h" |
13 #include "chrome/browser/safe_browsing/signature_util.h" | |
12 #include "chrome/common/net/http_return.h" | 14 #include "chrome/common/net/http_return.h" |
13 #include "chrome/common/safe_browsing/csd.pb.h" | 15 #include "chrome/common/safe_browsing/csd.pb.h" |
14 #include "content/browser/browser_thread.h" | 16 #include "content/browser/browser_thread.h" |
15 #include "net/base/load_flags.h" | 17 #include "net/base/load_flags.h" |
16 #include "net/url_request/url_request_context_getter.h" | 18 #include "net/url_request/url_request_context_getter.h" |
17 #include "net/url_request/url_request_status.h" | 19 #include "net/url_request/url_request_status.h" |
18 | 20 |
19 namespace safe_browsing { | 21 namespace safe_browsing { |
20 | 22 |
21 const char DownloadProtectionService::kDownloadRequestUrl[] = | 23 const char DownloadProtectionService::kDownloadRequestUrl[] = |
22 "https://sb-ssl.google.com/safebrowsing/clientreport/download"; | 24 "https://sb-ssl.google.com/safebrowsing/clientreport/download"; |
23 | 25 |
26 namespace { | |
27 bool IsBinaryFile(const FilePath& file) { | |
mattm
2011/10/19 18:54:12
"Binary" doesn't seem like quite the right term..
Brian Ryner
2011/10/19 19:20:11
I could use "executable" if you think that's bette
| |
28 FilePath::StringType extension = file.Extension(); | |
noelutz
2011/10/19 16:12:49
Maybe wrap this in StringToLowerASCII to make sure
Brian Ryner
2011/10/19 18:06:59
I ended up replacing this with calls to FilePath::
| |
29 return (EndsWith(extension, FILE_PATH_LITERAL("exe"), false) || | |
30 EndsWith(extension, FILE_PATH_LITERAL("cab"), false) || | |
31 EndsWith(extension, FILE_PATH_LITERAL("msi"), false)); | |
32 } | |
33 } // namespace | |
34 | |
24 DownloadProtectionService::DownloadInfo::DownloadInfo() | 35 DownloadProtectionService::DownloadInfo::DownloadInfo() |
25 : total_bytes(0), user_initiated(false) {} | 36 : total_bytes(0), user_initiated(false) {} |
26 | 37 |
27 DownloadProtectionService::DownloadInfo::~DownloadInfo() {} | 38 DownloadProtectionService::DownloadInfo::~DownloadInfo() {} |
28 | 39 |
29 DownloadProtectionService::DownloadProtectionService( | 40 DownloadProtectionService::DownloadProtectionService( |
30 SafeBrowsingService* sb_service, | 41 const base::WeakPtr<SafeBrowsingService>& sb_service, |
mattm
2011/10/19 18:54:12
Hmm, still not sure about these WeakPtr's but I'm
Brian Ryner
2011/10/19 19:20:11
Hm, good point. Maybe we need to AddRef the SafeB
| |
31 net::URLRequestContextGetter* request_context_getter) | 42 net::URLRequestContextGetter* request_context_getter) |
32 : sb_service_(sb_service), | 43 : sb_service_(sb_service), |
33 request_context_getter_(request_context_getter), | 44 request_context_getter_(request_context_getter), |
34 enabled_(false) {} | 45 enabled_(false) {} |
35 | 46 |
36 DownloadProtectionService::~DownloadProtectionService() { | 47 DownloadProtectionService::~DownloadProtectionService() { |
37 STLDeleteContainerPairFirstPointers(download_requests_.begin(), | 48 STLDeleteContainerPairFirstPointers(download_requests_.begin(), |
38 download_requests_.end()); | 49 download_requests_.end()); |
39 download_requests_.clear(); | 50 download_requests_.clear(); |
40 } | 51 } |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
113 if (info.download_url_chain.empty()) { | 124 if (info.download_url_chain.empty()) { |
114 RecordStats(REASON_INVALID_URL); | 125 RecordStats(REASON_INVALID_URL); |
115 return true; | 126 return true; |
116 } | 127 } |
117 const GURL& final_url = info.download_url_chain.back(); | 128 const GURL& final_url = info.download_url_chain.back(); |
118 if (!final_url.is_valid() || final_url.is_empty() || | 129 if (!final_url.is_valid() || final_url.is_empty() || |
119 !final_url.SchemeIs("http")) { | 130 !final_url.SchemeIs("http")) { |
120 RecordStats(REASON_INVALID_URL); | 131 RecordStats(REASON_INVALID_URL); |
121 return true; // For now we only support HTTP download URLs. | 132 return true; // For now we only support HTTP download URLs. |
122 } | 133 } |
134 | |
135 if (!IsBinaryFile(info.local_file)) { | |
136 RecordStats(REASON_NOT_BINARY_FILE); | |
137 return true; | |
138 } | |
139 | |
140 // Compute features from the file contents. Note that we record histograms | |
141 // based on the result, so this runs regardless of whether the pingbacks are | |
142 // enabled. Since we do blocking I/O, this happens on the file thread. | |
143 BrowserThread::PostTask( | |
144 BrowserThread::FILE, | |
145 FROM_HERE, | |
146 base::Bind(&DownloadProtectionService::ExtractFileFeatures, | |
147 this, info, callback)); | |
148 return false; | |
149 } | |
150 | |
151 void DownloadProtectionService::ExtractFileFeatures( | |
152 const DownloadInfo& info, | |
153 const CheckDownloadCallback& callback) { | |
154 if (safe_browsing::signature_util::IsSigned(info.local_file)) { | |
155 VLOG(2) << "Downloaded a signed binary: " << info.local_file.value(); | |
156 UMA_HISTOGRAM_COUNTS("SBClientDownload.SignedBinaryDownload", 1); | |
mattm
2011/10/19 18:54:12
Could use UMA_HISTOGRAM_BOOLEAN to get them both i
Brian Ryner
2011/10/19 19:20:11
Done.
| |
157 } else { | |
158 VLOG(2) << "Downloaded an unsigned binary: " << info.local_file.value(); | |
159 UMA_HISTOGRAM_COUNTS("SBClientDownload.UnsignedBinaryDownload", 1); | |
160 } | |
161 | |
123 // TODO(noelutz): DownloadInfo should also contain the IP address of every | 162 // TODO(noelutz): DownloadInfo should also contain the IP address of every |
124 // URL in the redirect chain. We also should check whether the download URL | 163 // URL in the redirect chain. We also should check whether the download URL |
125 // is hosted on the internal network. | 164 // is hosted on the internal network. |
126 BrowserThread::PostTask( | 165 BrowserThread::PostTask( |
127 BrowserThread::IO, | 166 BrowserThread::IO, |
128 FROM_HERE, | 167 FROM_HERE, |
129 base::Bind(&DownloadProtectionService::StartCheckClientDownload, | 168 base::Bind(&DownloadProtectionService::StartCheckClientDownload, |
130 this, info, callback)); | 169 this, info, callback)); |
131 return false; | |
132 } | 170 } |
133 | 171 |
134 void DownloadProtectionService::StartCheckClientDownload( | 172 void DownloadProtectionService::StartCheckClientDownload( |
135 const DownloadInfo& info, | 173 const DownloadInfo& info, |
136 const CheckDownloadCallback& callback) { | 174 const CheckDownloadCallback& callback) { |
137 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 175 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
138 if (!enabled_ || !sb_service_.get()) { | 176 if (!enabled_ || !sb_service_.get()) { |
139 // This is a hard fail. We won't even call the callback in this case. | 177 // This is a hard fail. We won't even call the callback in this case. |
140 RecordStats(REASON_SB_DISABLED); | 178 RecordStats(REASON_SB_DISABLED); |
noelutz
2011/10/19 16:12:49
Mhh. We might want to treat those two cases separ
Brian Ryner
2011/10/19 18:06:59
Is theree a reason we specifically want to avoid c
noelutz
2011/10/19 18:41:14
Good point. We can always call the callback with
| |
141 return; | 179 return; |
142 } | 180 } |
143 DownloadCheckResultReason reason = REASON_MAX; | 181 DownloadCheckResultReason reason = REASON_MAX; |
144 for (size_t i = 0; i < info.download_url_chain.size(); ++i) { | 182 for (size_t i = 0; i < info.download_url_chain.size(); ++i) { |
145 if (sb_service_->MatchDownloadWhitelistUrl(info.download_url_chain[i])) { | 183 if (sb_service_->MatchDownloadWhitelistUrl(info.download_url_chain[i])) { |
146 reason = REASON_WHITELISTED_URL; | 184 reason = REASON_WHITELISTED_URL; |
147 break; | 185 break; |
148 } | 186 } |
149 } | 187 } |
150 if (sb_service_->MatchDownloadWhitelistUrl(info.referrer_url)) { | 188 if (sb_service_->MatchDownloadWhitelistUrl(info.referrer_url)) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
203 RecordStats(reason); | 241 RecordStats(reason); |
204 callback.Run(result); | 242 callback.Run(result); |
205 } | 243 } |
206 | 244 |
207 void DownloadProtectionService::RecordStats(DownloadCheckResultReason reason) { | 245 void DownloadProtectionService::RecordStats(DownloadCheckResultReason reason) { |
208 UMA_HISTOGRAM_ENUMERATION("SBClientDownload.CheckDownloadStats", | 246 UMA_HISTOGRAM_ENUMERATION("SBClientDownload.CheckDownloadStats", |
209 reason, | 247 reason, |
210 REASON_MAX); | 248 REASON_MAX); |
211 } | 249 } |
212 } // namespace safe_browsing | 250 } // namespace safe_browsing |
OLD | NEW |