Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(119)

Side by Side Diff: chrome/browser/safe_browsing/download_protection_service.cc

Issue 2029903002: Add token field to ClientSafeBrowsingReportReqeust (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: tweak comments Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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 <stddef.h> 7 #include <stddef.h>
8 8
9 #include <memory> 9 #include <memory>
10 10
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 272
273 class DownloadProtectionService::CheckClientDownloadRequest 273 class DownloadProtectionService::CheckClientDownloadRequest
274 : public base::RefCountedThreadSafe< 274 : public base::RefCountedThreadSafe<
275 DownloadProtectionService::CheckClientDownloadRequest, 275 DownloadProtectionService::CheckClientDownloadRequest,
276 BrowserThread::DeleteOnUIThread>, 276 BrowserThread::DeleteOnUIThread>,
277 public net::URLFetcherDelegate, 277 public net::URLFetcherDelegate,
278 public content::DownloadItem::Observer { 278 public content::DownloadItem::Observer {
279 public: 279 public:
280 CheckClientDownloadRequest( 280 CheckClientDownloadRequest(
281 content::DownloadItem* item, 281 content::DownloadItem* item,
282 const CheckDownloadCallback& callback, 282 const CheckDownloadContentCallback& callback,
283 DownloadProtectionService* service, 283 DownloadProtectionService* service,
284 const scoped_refptr<SafeBrowsingDatabaseManager>& database_manager, 284 const scoped_refptr<SafeBrowsingDatabaseManager>& database_manager,
285 BinaryFeatureExtractor* binary_feature_extractor) 285 BinaryFeatureExtractor* binary_feature_extractor)
286 : item_(item), 286 : item_(item),
287 url_chain_(item->GetUrlChain()), 287 url_chain_(item->GetUrlChain()),
288 referrer_url_(item->GetReferrerUrl()), 288 referrer_url_(item->GetReferrerUrl()),
289 tab_url_(item->GetTabUrl()), 289 tab_url_(item->GetTabUrl()),
290 tab_referrer_url_(item->GetTabReferrerUrl()), 290 tab_referrer_url_(item->GetTabReferrerUrl()),
291 archived_executable_(false), 291 archived_executable_(false),
292 archive_is_valid_(ArchiveValid::UNSET), 292 archive_is_valid_(ArchiveValid::UNSET),
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 if (fetcher_.get()) { 415 if (fetcher_.get()) {
416 // The DownloadProtectionService is going to release its reference, so we 416 // The DownloadProtectionService is going to release its reference, so we
417 // might be destroyed before the URLFetcher completes. Cancel the 417 // might be destroyed before the URLFetcher completes. Cancel the
418 // fetcher so it does not try to invoke OnURLFetchComplete. 418 // fetcher so it does not try to invoke OnURLFetchComplete.
419 fetcher_.reset(); 419 fetcher_.reset();
420 } 420 }
421 // Note: If there is no fetcher, then some callback is still holding a 421 // Note: If there is no fetcher, then some callback is still holding a
422 // reference to this object. We'll eventually wind up in some method on 422 // reference to this object. We'll eventually wind up in some method on
423 // the UI thread that will call FinishRequest() again. If FinishRequest() 423 // the UI thread that will call FinishRequest() again. If FinishRequest()
424 // is called a second time, it will be a no-op. 424 // is called a second time, it will be a no-op.
425 FinishRequest(UNKNOWN, REASON_REQUEST_CANCELED); 425 FinishRequest(UNKNOWN, REASON_REQUEST_CANCELED, base::EmptyString());
426 // Calling FinishRequest might delete this object, we may be deleted by 426 // Calling FinishRequest might delete this object, we may be deleted by
427 // this point. 427 // this point.
428 } 428 }
429 429
430 // content::DownloadItem::Observer implementation. 430 // content::DownloadItem::Observer implementation.
431 void OnDownloadDestroyed(content::DownloadItem* download) override { 431 void OnDownloadDestroyed(content::DownloadItem* download) override {
432 Cancel(); 432 Cancel();
433 DCHECK(item_ == NULL); 433 DCHECK(item_ == NULL);
434 } 434 }
435 435
436 // From the net::URLFetcherDelegate interface. 436 // From the net::URLFetcherDelegate interface.
437 void OnURLFetchComplete(const net::URLFetcher* source) override { 437 void OnURLFetchComplete(const net::URLFetcher* source) override {
438 DCHECK_CURRENTLY_ON(BrowserThread::UI); 438 DCHECK_CURRENTLY_ON(BrowserThread::UI);
439 DCHECK_EQ(source, fetcher_.get()); 439 DCHECK_EQ(source, fetcher_.get());
440 DVLOG(2) << "Received a response for URL: " 440 DVLOG(2) << "Received a response for URL: "
441 << item_->GetUrlChain().back() << ": success=" 441 << item_->GetUrlChain().back() << ": success="
442 << source->GetStatus().is_success() << " response_code=" 442 << source->GetStatus().is_success() << " response_code="
443 << source->GetResponseCode(); 443 << source->GetResponseCode();
444 if (source->GetStatus().is_success()) { 444 if (source->GetStatus().is_success()) {
445 UMA_HISTOGRAM_SPARSE_SLOWLY( 445 UMA_HISTOGRAM_SPARSE_SLOWLY(
446 "SBClientDownload.DownloadRequestResponseCode", 446 "SBClientDownload.DownloadRequestResponseCode",
447 source->GetResponseCode()); 447 source->GetResponseCode());
448 } 448 }
449 UMA_HISTOGRAM_SPARSE_SLOWLY( 449 UMA_HISTOGRAM_SPARSE_SLOWLY(
450 "SBClientDownload.DownloadRequestNetError", 450 "SBClientDownload.DownloadRequestNetError",
451 -source->GetStatus().error()); 451 -source->GetStatus().error());
452 DownloadCheckResultReason reason = REASON_SERVER_PING_FAILED; 452 DownloadCheckResultReason reason = REASON_SERVER_PING_FAILED;
453 DownloadCheckResult result = UNKNOWN; 453 DownloadCheckResult result = UNKNOWN;
454 std::string token;
454 if (source->GetStatus().is_success() && 455 if (source->GetStatus().is_success() &&
455 net::HTTP_OK == source->GetResponseCode()) { 456 net::HTTP_OK == source->GetResponseCode()) {
456 ClientDownloadResponse response; 457 ClientDownloadResponse response;
457 std::string data; 458 std::string data;
458 bool got_data = source->GetResponseAsString(&data); 459 bool got_data = source->GetResponseAsString(&data);
459 DCHECK(got_data); 460 DCHECK(got_data);
460 if (!response.ParseFromString(data)) { 461 if (!response.ParseFromString(data)) {
461 reason = REASON_INVALID_RESPONSE_PROTO; 462 reason = REASON_INVALID_RESPONSE_PROTO;
462 result = UNKNOWN; 463 result = UNKNOWN;
463 } else if (response.verdict() == ClientDownloadResponse::SAFE) { 464 } else if (response.verdict() == ClientDownloadResponse::SAFE) {
464 reason = REASON_DOWNLOAD_SAFE; 465 reason = REASON_DOWNLOAD_SAFE;
465 result = SAFE; 466 result = SAFE;
466 } else if (service_ && !service_->IsSupportedDownload( 467 } else if (service_ && !service_->IsSupportedDownload(
467 *item_, item_->GetTargetFilePath())) { 468 *item_, item_->GetTargetFilePath())) {
468 // The client of the download protection service assumes that we don't 469 // The client of the download protection service assumes that we don't
469 // support this download so we cannot return any other verdict than 470 // support this download so we cannot return any other verdict than
470 // UNKNOWN even if the server says it's dangerous to download this file. 471 // UNKNOWN even if the server says it's dangerous to download this file.
471 // Note: if service_ is NULL we already cancelled the request and 472 // Note: if service_ is NULL we already cancelled the request and
472 // returned UNKNOWN. 473 // returned UNKNOWN.
473 reason = REASON_DOWNLOAD_NOT_SUPPORTED; 474 reason = REASON_DOWNLOAD_NOT_SUPPORTED;
474 result = UNKNOWN; 475 result = UNKNOWN;
475 } else if (response.verdict() == ClientDownloadResponse::DANGEROUS) { 476 } else if (response.verdict() == ClientDownloadResponse::DANGEROUS) {
476 reason = REASON_DOWNLOAD_DANGEROUS; 477 reason = REASON_DOWNLOAD_DANGEROUS;
477 result = DANGEROUS; 478 result = DANGEROUS;
479 token = response.has_token() ? response.token() : base::EmptyString();
478 } else if (response.verdict() == ClientDownloadResponse::UNCOMMON) { 480 } else if (response.verdict() == ClientDownloadResponse::UNCOMMON) {
479 reason = REASON_DOWNLOAD_UNCOMMON; 481 reason = REASON_DOWNLOAD_UNCOMMON;
480 result = UNCOMMON; 482 result = UNCOMMON;
483 token = response.has_token() ? response.token() : base::EmptyString();
481 } else if (response.verdict() == ClientDownloadResponse::DANGEROUS_HOST) { 484 } else if (response.verdict() == ClientDownloadResponse::DANGEROUS_HOST) {
482 reason = REASON_DOWNLOAD_DANGEROUS_HOST; 485 reason = REASON_DOWNLOAD_DANGEROUS_HOST;
483 result = DANGEROUS_HOST; 486 result = DANGEROUS_HOST;
487 token = response.has_token() ? response.token() : base::EmptyString();
484 } else if ( 488 } else if (
485 response.verdict() == ClientDownloadResponse::POTENTIALLY_UNWANTED) { 489 response.verdict() == ClientDownloadResponse::POTENTIALLY_UNWANTED) {
486 reason = REASON_DOWNLOAD_POTENTIALLY_UNWANTED; 490 reason = REASON_DOWNLOAD_POTENTIALLY_UNWANTED;
487 result = POTENTIALLY_UNWANTED; 491 result = POTENTIALLY_UNWANTED;
492 token = response.has_token() ? response.token() : base::EmptyString();
488 } else { 493 } else {
489 LOG(DFATAL) << "Unknown download response verdict: " 494 LOG(DFATAL) << "Unknown download response verdict: "
490 << response.verdict(); 495 << response.verdict();
491 reason = REASON_INVALID_RESPONSE_VERDICT; 496 reason = REASON_INVALID_RESPONSE_VERDICT;
492 result = UNKNOWN; 497 result = UNKNOWN;
493 } 498 }
494 DownloadFeedbackService::MaybeStorePingsForDownload( 499 DownloadFeedbackService::MaybeStorePingsForDownload(
495 result, item_, client_download_request_data_, data); 500 result, item_, client_download_request_data_, data);
496 } 501 }
497 // We don't need the fetcher anymore. 502 // We don't need the fetcher anymore.
498 fetcher_.reset(); 503 fetcher_.reset();
499 UMA_HISTOGRAM_TIMES("SBClientDownload.DownloadRequestDuration", 504 UMA_HISTOGRAM_TIMES("SBClientDownload.DownloadRequestDuration",
500 base::TimeTicks::Now() - start_time_); 505 base::TimeTicks::Now() - start_time_);
501 UMA_HISTOGRAM_TIMES("SBClientDownload.DownloadRequestNetworkDuration", 506 UMA_HISTOGRAM_TIMES("SBClientDownload.DownloadRequestNetworkDuration",
502 base::TimeTicks::Now() - request_start_time_); 507 base::TimeTicks::Now() - request_start_time_);
503 508
504 FinishRequest(result, reason); 509 FinishRequest(result, reason, token);
505 } 510 }
506 511
507 static bool IsSupportedDownload(const content::DownloadItem& item, 512 static bool IsSupportedDownload(const content::DownloadItem& item,
508 const base::FilePath& target_path, 513 const base::FilePath& target_path,
509 DownloadCheckResultReason* reason, 514 DownloadCheckResultReason* reason,
510 ClientDownloadRequest::DownloadType* type) { 515 ClientDownloadRequest::DownloadType* type) {
511 if (item.GetUrlChain().empty()) { 516 if (item.GetUrlChain().empty()) {
512 *reason = REASON_EMPTY_URL_CHAIN; 517 *reason = REASON_EMPTY_URL_CHAIN;
513 return false; 518 return false;
514 } 519 }
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
931 item_->GetTargetFilePath().BaseName().AsUTF8Unsafe()); 936 item_->GetTargetFilePath().BaseName().AsUTF8Unsafe());
932 request.set_download_type(type_); 937 request.set_download_type(type_);
933 if (archive_is_valid_ != ArchiveValid::UNSET) 938 if (archive_is_valid_ != ArchiveValid::UNSET)
934 request.set_archive_valid(archive_is_valid_ == ArchiveValid::VALID); 939 request.set_archive_valid(archive_is_valid_ == ArchiveValid::VALID);
935 request.mutable_signature()->CopyFrom(signature_info_); 940 request.mutable_signature()->CopyFrom(signature_info_);
936 if (image_headers_) 941 if (image_headers_)
937 request.set_allocated_image_headers(image_headers_.release()); 942 request.set_allocated_image_headers(image_headers_.release());
938 if (archived_executable_) 943 if (archived_executable_)
939 request.mutable_archived_binary()->Swap(&archived_binary_); 944 request.mutable_archived_binary()->Swap(&archived_binary_);
940 if (!request.SerializeToString(&client_download_request_data_)) { 945 if (!request.SerializeToString(&client_download_request_data_)) {
941 FinishRequest(UNKNOWN, REASON_INVALID_REQUEST_PROTO); 946 FinishRequest(UNKNOWN, REASON_INVALID_REQUEST_PROTO, base::EmptyString());
942 return; 947 return;
943 } 948 }
944 949
945 // User can manually blacklist a sha256 via flag, for testing. 950 // User can manually blacklist a sha256 via flag, for testing.
946 // This is checked just before the request is sent, to verify the request 951 // This is checked just before the request is sent, to verify the request
947 // would have been sent. This emmulates the server returning a DANGEROUS 952 // would have been sent. This emmulates the server returning a DANGEROUS
948 // verdict as closely as possible. 953 // verdict as closely as possible.
949 if (IsDownloadManuallyBlacklisted(request)) { 954 if (IsDownloadManuallyBlacklisted(request)) {
950 DVLOG(1) << "Download verdict overridden to DANGEROUS by flag."; 955 DVLOG(1) << "Download verdict overridden to DANGEROUS by flag.";
951 PostFinishTask(DANGEROUS, REASON_MANUAL_BLACKLIST); 956 PostFinishTask(DANGEROUS, REASON_MANUAL_BLACKLIST);
(...skipping 18 matching lines...) Expand all
970 client_download_request_data_.size()); 975 client_download_request_data_.size());
971 fetcher_->Start(); 976 fetcher_->Start();
972 } 977 }
973 978
974 void PostFinishTask(DownloadCheckResult result, 979 void PostFinishTask(DownloadCheckResult result,
975 DownloadCheckResultReason reason) { 980 DownloadCheckResultReason reason) {
976 BrowserThread::PostTask( 981 BrowserThread::PostTask(
977 BrowserThread::UI, 982 BrowserThread::UI,
978 FROM_HERE, 983 FROM_HERE,
979 base::Bind(&CheckClientDownloadRequest::FinishRequest, this, result, 984 base::Bind(&CheckClientDownloadRequest::FinishRequest, this, result,
980 reason)); 985 reason, base::EmptyString()));
981 } 986 }
982 987
983 void FinishRequest(DownloadCheckResult result, 988 void FinishRequest(DownloadCheckResult result,
984 DownloadCheckResultReason reason) { 989 DownloadCheckResultReason reason,
990 const std::string& token) {
985 DCHECK_CURRENTLY_ON(BrowserThread::UI); 991 DCHECK_CURRENTLY_ON(BrowserThread::UI);
986 if (finished_) { 992 if (finished_) {
987 return; 993 return;
988 } 994 }
989 finished_ = true; 995 finished_ = true;
990 996
991 // Ensure the timeout task is cancelled while we still have a non-zero 997 // Ensure the timeout task is cancelled while we still have a non-zero
992 // refcount. (crbug.com/240449) 998 // refcount. (crbug.com/240449)
993 weakptr_factory_.InvalidateWeakPtrs(); 999 weakptr_factory_.InvalidateWeakPtrs();
994 if (!request_start_time_.is_null()) { 1000 if (!request_start_time_.is_null()) {
(...skipping 10 matching lines...) Expand all
1005 base::TimeTicks::Now() - timeout_start_time_); 1011 base::TimeTicks::Now() - timeout_start_time_);
1006 } 1012 }
1007 } 1013 }
1008 if (service_) { 1014 if (service_) {
1009 DVLOG(2) << "SafeBrowsing download verdict for: " 1015 DVLOG(2) << "SafeBrowsing download verdict for: "
1010 << item_->DebugString(true) << " verdict:" << reason 1016 << item_->DebugString(true) << " verdict:" << reason
1011 << " result:" << result; 1017 << " result:" << result;
1012 UMA_HISTOGRAM_ENUMERATION("SBClientDownload.CheckDownloadStats", 1018 UMA_HISTOGRAM_ENUMERATION("SBClientDownload.CheckDownloadStats",
1013 reason, 1019 reason,
1014 REASON_MAX); 1020 REASON_MAX);
1015 callback_.Run(result); 1021 callback_.Run(result, token);
1016 item_->RemoveObserver(this); 1022 item_->RemoveObserver(this);
1017 item_ = NULL; 1023 item_ = NULL;
1018 DownloadProtectionService* service = service_; 1024 DownloadProtectionService* service = service_;
1019 service_ = NULL; 1025 service_ = NULL;
1020 service->RequestFinished(this); 1026 service->RequestFinished(this);
1021 // DownloadProtectionService::RequestFinished will decrement our refcount, 1027 // DownloadProtectionService::RequestFinished will decrement our refcount,
1022 // so we may be deleted now. 1028 // so we may be deleted now.
1023 } else { 1029 } else {
1024 callback_.Run(UNKNOWN); 1030 callback_.Run(UNKNOWN, base::EmptyString());
1025 } 1031 }
1026 } 1032 }
1027 1033
1028 bool CertificateChainIsWhitelisted( 1034 bool CertificateChainIsWhitelisted(
1029 const ClientDownloadRequest_CertificateChain& chain) { 1035 const ClientDownloadRequest_CertificateChain& chain) {
1030 DCHECK_CURRENTLY_ON(BrowserThread::IO); 1036 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1031 if (chain.element_size() < 2) { 1037 if (chain.element_size() < 2) {
1032 // We need to have both a signing certificate and its issuer certificate 1038 // We need to have both a signing certificate and its issuer certificate
1033 // present to construct a whitelist entry. 1039 // present to construct a whitelist entry.
1034 return false; 1040 return false;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1080 GURL tab_url_; 1086 GURL tab_url_;
1081 GURL tab_referrer_url_; 1087 GURL tab_referrer_url_;
1082 1088
1083 bool archived_executable_; 1089 bool archived_executable_;
1084 ArchiveValid archive_is_valid_; 1090 ArchiveValid archive_is_valid_;
1085 1091
1086 ClientDownloadRequest_SignatureInfo signature_info_; 1092 ClientDownloadRequest_SignatureInfo signature_info_;
1087 std::unique_ptr<ClientDownloadRequest_ImageHeaders> image_headers_; 1093 std::unique_ptr<ClientDownloadRequest_ImageHeaders> image_headers_;
1088 google::protobuf::RepeatedPtrField<ClientDownloadRequest_ArchivedBinary> 1094 google::protobuf::RepeatedPtrField<ClientDownloadRequest_ArchivedBinary>
1089 archived_binary_; 1095 archived_binary_;
1090 CheckDownloadCallback callback_; 1096 CheckDownloadContentCallback callback_;
1091 // Will be NULL if the request has been canceled. 1097 // Will be NULL if the request has been canceled.
1092 DownloadProtectionService* service_; 1098 DownloadProtectionService* service_;
1093 scoped_refptr<BinaryFeatureExtractor> binary_feature_extractor_; 1099 scoped_refptr<BinaryFeatureExtractor> binary_feature_extractor_;
1094 scoped_refptr<SafeBrowsingDatabaseManager> database_manager_; 1100 scoped_refptr<SafeBrowsingDatabaseManager> database_manager_;
1095 const bool pingback_enabled_; 1101 const bool pingback_enabled_;
1096 std::unique_ptr<net::URLFetcher> fetcher_; 1102 std::unique_ptr<net::URLFetcher> fetcher_;
1097 scoped_refptr<SandboxedZipAnalyzer> analyzer_; 1103 scoped_refptr<SandboxedZipAnalyzer> analyzer_;
1098 base::TimeTicks zip_analysis_start_time_; 1104 base::TimeTicks zip_analysis_start_time_;
1099 #if defined(OS_MACOSX) 1105 #if defined(OS_MACOSX)
1100 scoped_refptr<SandboxedDMGAnalyzer> dmg_analyzer_; 1106 scoped_refptr<SandboxedDMGAnalyzer> dmg_analyzer_;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1143 REQUEST_MALFORMED, 1149 REQUEST_MALFORMED,
1144 FETCH_FAILED, 1150 FETCH_FAILED,
1145 RESPONSE_MALFORMED, 1151 RESPONSE_MALFORMED,
1146 SUCCEEDED 1152 SUCCEEDED
1147 }; 1153 };
1148 1154
1149 PPAPIDownloadRequest( 1155 PPAPIDownloadRequest(
1150 const GURL& requestor_url, 1156 const GURL& requestor_url,
1151 const base::FilePath& default_file_path, 1157 const base::FilePath& default_file_path,
1152 const std::vector<base::FilePath::StringType>& alternate_extensions, 1158 const std::vector<base::FilePath::StringType>& alternate_extensions,
1153 const CheckDownloadCallback& callback, 1159 const CheckDownloadContentCallback& callback,
1154 DownloadProtectionService* service, 1160 DownloadProtectionService* service,
1155 scoped_refptr<SafeBrowsingDatabaseManager> database_manager) 1161 scoped_refptr<SafeBrowsingDatabaseManager> database_manager)
1156 : requestor_url_(requestor_url), 1162 : requestor_url_(requestor_url),
1157 default_file_path_(default_file_path), 1163 default_file_path_(default_file_path),
1158 alternate_extensions_(alternate_extensions), 1164 alternate_extensions_(alternate_extensions),
1159 callback_(callback), 1165 callback_(callback),
1160 service_(service), 1166 service_(service),
1161 database_manager_(database_manager), 1167 database_manager_(database_manager),
1162 start_time_(base::TimeTicks::Now()), 1168 start_time_(base::TimeTicks::Now()),
1163 supported_path_( 1169 supported_path_(
1164 GetSupportedFilePath(default_file_path, alternate_extensions)), 1170 GetSupportedFilePath(default_file_path, alternate_extensions)),
1165 weakptr_factory_(this) {} 1171 weakptr_factory_(this) {}
1166 1172
1167 ~PPAPIDownloadRequest() override { 1173 ~PPAPIDownloadRequest() override {
1168 if (fetcher_ && !callback_.is_null()) 1174 if (fetcher_ && !callback_.is_null())
1169 Finish(RequestOutcome::REQUEST_DESTROYED, UNKNOWN); 1175 Finish(RequestOutcome::REQUEST_DESTROYED, UNKNOWN, base::EmptyString());
1170 } 1176 }
1171 1177
1172 // Start the process of checking the download request. The callback passed as 1178 // Start the process of checking the download request. The callback passed as
1173 // the |callback| parameter to the constructor will be invoked with the result 1179 // the |callback| parameter to the constructor will be invoked with the result
1174 // of the check at some point in the future. 1180 // of the check at some point in the future.
1175 // 1181 //
1176 // From the this point on, the code is arranged to follow the most common 1182 // From the this point on, the code is arranged to follow the most common
1177 // workflow. 1183 // workflow.
1178 // 1184 //
1179 // Note that |this| should be added to the list of pending requests in the 1185 // Note that |this| should be added to the list of pending requests in the
1180 // associated DownloadProtectionService object *before* calling Start(). 1186 // associated DownloadProtectionService object *before* calling Start().
1181 // Otherwise a synchronous Finish() call may result in leaking the 1187 // Otherwise a synchronous Finish() call may result in leaking the
1182 // PPAPIDownloadRequest object. This is enforced via a DCHECK in 1188 // PPAPIDownloadRequest object. This is enforced via a DCHECK in
1183 // DownloadProtectionService. 1189 // DownloadProtectionService.
1184 void Start() { 1190 void Start() {
1185 DVLOG(2) << "Starting SafeBrowsing download check for PPAPI download from " 1191 DVLOG(2) << "Starting SafeBrowsing download check for PPAPI download from "
1186 << requestor_url_ << " for [" << default_file_path_.value() << "] " 1192 << requestor_url_ << " for [" << default_file_path_.value() << "] "
1187 << "supported path is [" << supported_path_.value() << "]"; 1193 << "supported path is [" << supported_path_.value() << "]";
1188 1194
1189 if (supported_path_.empty()) { 1195 if (supported_path_.empty()) {
1190 // Neither the default_file_path_ nor any path resulting of trying out 1196 // Neither the default_file_path_ nor any path resulting of trying out
1191 // |alternate_extensions_| are supported by SafeBrowsing. 1197 // |alternate_extensions_| are supported by SafeBrowsing.
1192 Finish(RequestOutcome::UNSUPPORTED_FILE_TYPE, SAFE); 1198 Finish(RequestOutcome::UNSUPPORTED_FILE_TYPE, SAFE, base::EmptyString());
1193 return; 1199 return;
1194 } 1200 }
1195 1201
1196 // In case the request take too long, the check will abort with an UNKNOWN 1202 // In case the request take too long, the check will abort with an UNKNOWN
1197 // verdict. The weak pointer used for the timeout will be invalidated (and 1203 // verdict. The weak pointer used for the timeout will be invalidated (and
1198 // hence would prevent the timeout) if the check completes on time and 1204 // hence would prevent the timeout) if the check completes on time and
1199 // execution reaches Finish(). 1205 // execution reaches Finish().
1200 BrowserThread::PostDelayedTask( 1206 BrowserThread::PostDelayedTask(
1201 BrowserThread::UI, FROM_HERE, 1207 BrowserThread::UI, FROM_HERE,
1202 base::Bind(&PPAPIDownloadRequest::OnRequestTimedOut, 1208 base::Bind(&PPAPIDownloadRequest::OnRequestTimedOut,
(...skipping 24 matching lines...) Expand all
1227 BrowserThread::UI, FROM_HERE, 1233 BrowserThread::UI, FROM_HERE,
1228 base::Bind(&PPAPIDownloadRequest::WhitelistCheckComplete, 1234 base::Bind(&PPAPIDownloadRequest::WhitelistCheckComplete,
1229 download_request, url_was_whitelisted)); 1235 download_request, url_was_whitelisted));
1230 } 1236 }
1231 1237
1232 void WhitelistCheckComplete(bool was_on_whitelist) { 1238 void WhitelistCheckComplete(bool was_on_whitelist) {
1233 DVLOG(2) << __FUNCTION__ << " was_on_whitelist:" << was_on_whitelist; 1239 DVLOG(2) << __FUNCTION__ << " was_on_whitelist:" << was_on_whitelist;
1234 if (was_on_whitelist) { 1240 if (was_on_whitelist) {
1235 // TODO(asanka): Should sample whitelisted downloads based on 1241 // TODO(asanka): Should sample whitelisted downloads based on
1236 // service_->whitelist_sample_rate(). http://crbug.com/610924 1242 // service_->whitelist_sample_rate(). http://crbug.com/610924
1237 Finish(RequestOutcome::WHITELIST_HIT, SAFE); 1243 Finish(RequestOutcome::WHITELIST_HIT, SAFE, base::EmptyString());
1238 return; 1244 return;
1239 } 1245 }
1240 1246
1241 // Not on whitelist, so we are going to check with the SafeBrowsing 1247 // Not on whitelist, so we are going to check with the SafeBrowsing
1242 // backend. 1248 // backend.
1243 SendRequest(); 1249 SendRequest();
1244 } 1250 }
1245 1251
1246 void SendRequest() { 1252 void SendRequest() {
1247 DVLOG(2) << __FUNCTION__; 1253 DVLOG(2) << __FUNCTION__;
(...skipping 16 matching lines...) Expand all
1264 base::FilePath(alternate_extension).AsUTF8Unsafe(); 1270 base::FilePath(alternate_extension).AsUTF8Unsafe();
1265 } 1271 }
1266 if (supported_path_ != default_file_path_) { 1272 if (supported_path_ != default_file_path_) {
1267 *(request.add_alternate_extensions()) = 1273 *(request.add_alternate_extensions()) =
1268 base::FilePath(default_file_path_.FinalExtension()).AsUTF8Unsafe(); 1274 base::FilePath(default_file_path_.FinalExtension()).AsUTF8Unsafe();
1269 } 1275 }
1270 1276
1271 if (!request.SerializeToString(&client_download_request_data_)) { 1277 if (!request.SerializeToString(&client_download_request_data_)) {
1272 // More of an internal error than anything else. Note that the UNKNOWN 1278 // More of an internal error than anything else. Note that the UNKNOWN
1273 // verdict gets interpreted as "allowed". 1279 // verdict gets interpreted as "allowed".
1274 Finish(RequestOutcome::REQUEST_MALFORMED, UNKNOWN); 1280 Finish(RequestOutcome::REQUEST_MALFORMED, UNKNOWN, base::EmptyString());
1275 return; 1281 return;
1276 } 1282 }
1277 1283
1278 fetcher_ = net::URLFetcher::Create(0, GetDownloadRequestUrl(), 1284 fetcher_ = net::URLFetcher::Create(0, GetDownloadRequestUrl(),
1279 net::URLFetcher::POST, this); 1285 net::URLFetcher::POST, this);
1280 fetcher_->SetLoadFlags(net::LOAD_DISABLE_CACHE); 1286 fetcher_->SetLoadFlags(net::LOAD_DISABLE_CACHE);
1281 fetcher_->SetAutomaticallyRetryOn5xx(false); 1287 fetcher_->SetAutomaticallyRetryOn5xx(false);
1282 fetcher_->SetRequestContext(service_->request_context_getter_.get()); 1288 fetcher_->SetRequestContext(service_->request_context_getter_.get());
1283 fetcher_->SetUploadData("application/octet-stream", 1289 fetcher_->SetUploadData("application/octet-stream",
1284 client_download_request_data_); 1290 client_download_request_data_);
1285 fetcher_->Start(); 1291 fetcher_->Start();
1286 } 1292 }
1287 1293
1288 // net::URLFetcherDelegate 1294 // net::URLFetcherDelegate
1289 void OnURLFetchComplete(const net::URLFetcher* source) override { 1295 void OnURLFetchComplete(const net::URLFetcher* source) override {
1290 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1296 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1291 1297
1292 if (!source->GetStatus().is_success() || 1298 if (!source->GetStatus().is_success() ||
1293 net::HTTP_OK != source->GetResponseCode()) { 1299 net::HTTP_OK != source->GetResponseCode()) {
1294 Finish(RequestOutcome::FETCH_FAILED, UNKNOWN); 1300 Finish(RequestOutcome::FETCH_FAILED, UNKNOWN, base::EmptyString());
1295 return; 1301 return;
1296 } 1302 }
1297 1303
1298 ClientDownloadResponse response; 1304 ClientDownloadResponse response;
1299 std::string response_body; 1305 std::string response_body;
1306 std::string token;
1300 bool got_data = source->GetResponseAsString(&response_body); 1307 bool got_data = source->GetResponseAsString(&response_body);
1301 DCHECK(got_data); 1308 DCHECK(got_data);
1302 1309
1303 if (response.ParseFromString(response_body)) { 1310 if (response.ParseFromString(response_body)) {
1311 token = response.has_token() ? response.token() : base::EmptyString();
1304 Finish(RequestOutcome::SUCCEEDED, 1312 Finish(RequestOutcome::SUCCEEDED,
1305 DownloadCheckResultFromClientDownloadResponse(response.verdict())); 1313 DownloadCheckResultFromClientDownloadResponse(response.verdict()),
1314 token);
1306 } else { 1315 } else {
1307 Finish(RequestOutcome::RESPONSE_MALFORMED, UNKNOWN); 1316 Finish(RequestOutcome::RESPONSE_MALFORMED, UNKNOWN, base::EmptyString());
1308 } 1317 }
1309 } 1318 }
1310 1319
1311 void OnRequestTimedOut() { 1320 void OnRequestTimedOut() {
1312 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1321 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1313 DVLOG(2) << __FUNCTION__; 1322 DVLOG(2) << __FUNCTION__;
1314 Finish(RequestOutcome::TIMEDOUT, UNKNOWN); 1323 Finish(RequestOutcome::TIMEDOUT, UNKNOWN, base::EmptyString());
1315 } 1324 }
1316 1325
1317 void Finish(RequestOutcome reason, DownloadCheckResult response) { 1326 void Finish(RequestOutcome reason,
1327 DownloadCheckResult response,
1328 const std::string& token) {
1318 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1329 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1319 DVLOG(2) << __FUNCTION__ << " response: " << response; 1330 DVLOG(2) << __FUNCTION__ << " response: " << response;
1320 UMA_HISTOGRAM_SPARSE_SLOWLY( 1331 UMA_HISTOGRAM_SPARSE_SLOWLY(
1321 "SBClientDownload.PPAPIDownloadRequest.RequestOutcome", 1332 "SBClientDownload.PPAPIDownloadRequest.RequestOutcome",
1322 static_cast<int>(reason)); 1333 static_cast<int>(reason));
1323 UMA_HISTOGRAM_SPARSE_SLOWLY("SBClientDownload.PPAPIDownloadRequest.Result", 1334 UMA_HISTOGRAM_SPARSE_SLOWLY("SBClientDownload.PPAPIDownloadRequest.Result",
1324 response); 1335 response);
1325 UMA_HISTOGRAM_TIMES("SBClientDownload.PPAPIDownloadRequest.RequestDuration", 1336 UMA_HISTOGRAM_TIMES("SBClientDownload.PPAPIDownloadRequest.RequestDuration",
1326 start_time_ - base::TimeTicks::Now()); 1337 start_time_ - base::TimeTicks::Now());
1327 if (!callback_.is_null()) 1338 if (!callback_.is_null())
1328 base::ResetAndReturn(&callback_).Run(response); 1339 base::ResetAndReturn(&callback_).Run(response, token);
1329 fetcher_.reset(); 1340 fetcher_.reset();
1330 weakptr_factory_.InvalidateWeakPtrs(); 1341 weakptr_factory_.InvalidateWeakPtrs();
1331 service_->PPAPIDownloadCheckRequestFinished(this); 1342 service_->PPAPIDownloadCheckRequestFinished(this);
1332 // |this| is deleted. 1343 // |this| is deleted.
1333 } 1344 }
1334 1345
1335 static DownloadCheckResult DownloadCheckResultFromClientDownloadResponse( 1346 static DownloadCheckResult DownloadCheckResultFromClientDownloadResponse(
1336 ClientDownloadResponse::Verdict verdict) { 1347 ClientDownloadResponse::Verdict verdict) {
1337 switch (verdict) { 1348 switch (verdict) {
1338 case ClientDownloadResponse::SAFE: 1349 case ClientDownloadResponse::SAFE:
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1378 const GURL requestor_url_; 1389 const GURL requestor_url_;
1379 1390
1380 // Default download path requested by the PPAPI plugin. 1391 // Default download path requested by the PPAPI plugin.
1381 const base::FilePath default_file_path_; 1392 const base::FilePath default_file_path_;
1382 1393
1383 // List of alternate extensions provided by the PPAPI plugin. Each extension 1394 // List of alternate extensions provided by the PPAPI plugin. Each extension
1384 // must begin with a leading extension separator. 1395 // must begin with a leading extension separator.
1385 const std::vector<base::FilePath::StringType> alternate_extensions_; 1396 const std::vector<base::FilePath::StringType> alternate_extensions_;
1386 1397
1387 // Callback to invoke with the result of the PPAPI download request check. 1398 // Callback to invoke with the result of the PPAPI download request check.
1388 CheckDownloadCallback callback_; 1399 CheckDownloadContentCallback callback_;
1389 1400
1390 DownloadProtectionService* service_; 1401 DownloadProtectionService* service_;
1391 const scoped_refptr<SafeBrowsingDatabaseManager> database_manager_; 1402 const scoped_refptr<SafeBrowsingDatabaseManager> database_manager_;
1392 1403
1393 // Time request was started. 1404 // Time request was started.
1394 const base::TimeTicks start_time_; 1405 const base::TimeTicks start_time_;
1395 1406
1396 // A download path that is supported by SafeBrowsing. This is determined by 1407 // A download path that is supported by SafeBrowsing. This is determined by
1397 // invoking GetSupportedFilePath(). If non-empty, 1408 // invoking GetSupportedFilePath(). If non-empty,
1398 // safe_browsing::IsSupportedBinaryFile(supported_path_) is always true. This 1409 // safe_browsing::IsSupportedBinaryFile(supported_path_) is always true. This
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1459 } 1470 }
1460 } 1471 }
1461 1472
1462 bool DownloadProtectionService::IsHashManuallyBlacklisted( 1473 bool DownloadProtectionService::IsHashManuallyBlacklisted(
1463 const std::string& sha256_hash) const { 1474 const std::string& sha256_hash) const {
1464 return manual_blacklist_hashes_.count(sha256_hash) > 0; 1475 return manual_blacklist_hashes_.count(sha256_hash) > 0;
1465 } 1476 }
1466 1477
1467 void DownloadProtectionService::CheckClientDownload( 1478 void DownloadProtectionService::CheckClientDownload(
1468 content::DownloadItem* item, 1479 content::DownloadItem* item,
1469 const CheckDownloadCallback& callback) { 1480 const CheckDownloadContentCallback& callback) {
1470 scoped_refptr<CheckClientDownloadRequest> request( 1481 scoped_refptr<CheckClientDownloadRequest> request(
1471 new CheckClientDownloadRequest(item, callback, this, 1482 new CheckClientDownloadRequest(item, callback, this,
1472 database_manager_, 1483 database_manager_,
1473 binary_feature_extractor_.get())); 1484 binary_feature_extractor_.get()));
1474 download_requests_.insert(request); 1485 download_requests_.insert(request);
1475 request->Start(); 1486 request->Start();
1476 } 1487 }
1477 1488
1478 void DownloadProtectionService::CheckDownloadUrl( 1489 void DownloadProtectionService::CheckDownloadUrl(
1479 const content::DownloadItem& item, 1490 const content::DownloadItem& item,
(...skipping 16 matching lines...) Expand all
1496 ClientDownloadRequest::WIN_EXECUTABLE; 1507 ClientDownloadRequest::WIN_EXECUTABLE;
1497 return (CheckClientDownloadRequest::IsSupportedDownload( 1508 return (CheckClientDownloadRequest::IsSupportedDownload(
1498 item, target_path, &reason, &type) && 1509 item, target_path, &reason, &type) &&
1499 (ClientDownloadRequest::CHROME_EXTENSION != type)); 1510 (ClientDownloadRequest::CHROME_EXTENSION != type));
1500 } 1511 }
1501 1512
1502 void DownloadProtectionService::CheckPPAPIDownloadRequest( 1513 void DownloadProtectionService::CheckPPAPIDownloadRequest(
1503 const GURL& requestor_url, 1514 const GURL& requestor_url,
1504 const base::FilePath& default_file_path, 1515 const base::FilePath& default_file_path,
1505 const std::vector<base::FilePath::StringType>& alternate_extensions, 1516 const std::vector<base::FilePath::StringType>& alternate_extensions,
1506 const CheckDownloadCallback& callback) { 1517 const CheckDownloadContentCallback& callback) {
1507 DVLOG(1) << __FUNCTION__ << " url:" << requestor_url 1518 DVLOG(1) << __FUNCTION__ << " url:" << requestor_url
1508 << " default_file_path:" << default_file_path.value(); 1519 << " default_file_path:" << default_file_path.value();
1509 std::unique_ptr<PPAPIDownloadRequest> request(new PPAPIDownloadRequest( 1520 std::unique_ptr<PPAPIDownloadRequest> request(new PPAPIDownloadRequest(
1510 requestor_url, default_file_path, alternate_extensions, callback, this, 1521 requestor_url, default_file_path, alternate_extensions, callback, this,
1511 database_manager_)); 1522 database_manager_));
1512 PPAPIDownloadRequest* request_copy = request.get(); 1523 PPAPIDownloadRequest* request_copy = request.get();
1513 auto insertion_result = ppapi_download_requests_.insert( 1524 auto insertion_result = ppapi_download_requests_.insert(
1514 std::make_pair(request_copy, std::move(request))); 1525 std::make_pair(request_copy, std::move(request)));
1515 DCHECK(insertion_result.second); 1526 DCHECK(insertion_result.second);
1516 insertion_result.first->second->Start(); 1527 insertion_result.first->second->Start();
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1649 GURL DownloadProtectionService::GetDownloadRequestUrl() { 1660 GURL DownloadProtectionService::GetDownloadRequestUrl() {
1650 GURL url(kDownloadRequestUrl); 1661 GURL url(kDownloadRequestUrl);
1651 std::string api_key = google_apis::GetAPIKey(); 1662 std::string api_key = google_apis::GetAPIKey();
1652 if (!api_key.empty()) 1663 if (!api_key.empty())
1653 url = url.Resolve("?key=" + net::EscapeQueryParamValue(api_key, true)); 1664 url = url.Resolve("?key=" + net::EscapeQueryParamValue(api_key, true));
1654 1665
1655 return url; 1666 return url;
1656 } 1667 }
1657 1668
1658 } // namespace safe_browsing 1669 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698