OLD | NEW |
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 "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 304 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
305 // TODO(noelutz): implement some cache to make sure we don't issue the same | 305 // TODO(noelutz): implement some cache to make sure we don't issue the same |
306 // request over and over again if a user downloads the same binary multiple | 306 // request over and over again if a user downloads the same binary multiple |
307 // times. | 307 // times. |
308 DownloadCheckResultReason reason = REASON_MAX; | 308 DownloadCheckResultReason reason = REASON_MAX; |
309 if (!IsSupportedDownload( | 309 if (!IsSupportedDownload( |
310 *item_, item_->GetTargetFilePath(), &reason, &type_)) { | 310 *item_, item_->GetTargetFilePath(), &reason, &type_)) { |
311 switch (reason) { | 311 switch (reason) { |
312 case REASON_EMPTY_URL_CHAIN: | 312 case REASON_EMPTY_URL_CHAIN: |
313 case REASON_INVALID_URL: | 313 case REASON_INVALID_URL: |
314 PostFinishTask(SAFE, reason); | 314 PostFinishTask(UNKNOWN, reason); |
315 return; | 315 return; |
316 | 316 |
317 case REASON_NOT_BINARY_FILE: | 317 case REASON_NOT_BINARY_FILE: |
318 RecordFileExtensionType(item_->GetTargetFilePath()); | 318 RecordFileExtensionType(item_->GetTargetFilePath()); |
319 PostFinishTask(SAFE, reason); | 319 PostFinishTask(UNKNOWN, reason); |
320 return; | 320 return; |
321 | 321 |
322 default: | 322 default: |
323 // We only expect the reasons explicitly handled above. | 323 // We only expect the reasons explicitly handled above. |
324 NOTREACHED(); | 324 NOTREACHED(); |
325 } | 325 } |
326 } | 326 } |
327 RecordFileExtensionType(item_->GetTargetFilePath()); | 327 RecordFileExtensionType(item_->GetTargetFilePath()); |
328 | 328 |
329 // Compute features from the file contents. Note that we record histograms | 329 // Compute features from the file contents. Note that we record histograms |
(...skipping 20 matching lines...) Expand all Loading... |
350 timeout_start_time_ = base::TimeTicks::Now(); | 350 timeout_start_time_ = base::TimeTicks::Now(); |
351 BrowserThread::PostDelayedTask( | 351 BrowserThread::PostDelayedTask( |
352 BrowserThread::UI, | 352 BrowserThread::UI, |
353 FROM_HERE, | 353 FROM_HERE, |
354 base::Bind(&CheckClientDownloadRequest::Cancel, | 354 base::Bind(&CheckClientDownloadRequest::Cancel, |
355 weakptr_factory_.GetWeakPtr()), | 355 weakptr_factory_.GetWeakPtr()), |
356 base::TimeDelta::FromMilliseconds( | 356 base::TimeDelta::FromMilliseconds( |
357 service_->download_request_timeout_ms())); | 357 service_->download_request_timeout_ms())); |
358 } | 358 } |
359 | 359 |
360 // Canceling a request will cause us to always report the result as SAFE | 360 // Canceling a request will cause us to always report the result as UNKNOWN |
361 // unless a pending request is about to call FinishRequest. | 361 // unless a pending request is about to call FinishRequest. |
362 void Cancel() { | 362 void Cancel() { |
363 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 363 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
364 if (fetcher_.get()) { | 364 if (fetcher_.get()) { |
365 // The DownloadProtectionService is going to release its reference, so we | 365 // The DownloadProtectionService is going to release its reference, so we |
366 // might be destroyed before the URLFetcher completes. Cancel the | 366 // might be destroyed before the URLFetcher completes. Cancel the |
367 // fetcher so it does not try to invoke OnURLFetchComplete. | 367 // fetcher so it does not try to invoke OnURLFetchComplete. |
368 fetcher_.reset(); | 368 fetcher_.reset(); |
369 } | 369 } |
370 // Note: If there is no fetcher, then some callback is still holding a | 370 // Note: If there is no fetcher, then some callback is still holding a |
371 // reference to this object. We'll eventually wind up in some method on | 371 // reference to this object. We'll eventually wind up in some method on |
372 // the UI thread that will call FinishRequest() again. If FinishRequest() | 372 // the UI thread that will call FinishRequest() again. If FinishRequest() |
373 // is called a second time, it will be a no-op. | 373 // is called a second time, it will be a no-op. |
374 FinishRequest(SAFE, REASON_REQUEST_CANCELED); | 374 FinishRequest(UNKNOWN, REASON_REQUEST_CANCELED); |
375 // Calling FinishRequest might delete this object, we may be deleted by | 375 // Calling FinishRequest might delete this object, we may be deleted by |
376 // this point. | 376 // this point. |
377 } | 377 } |
378 | 378 |
379 // content::DownloadItem::Observer implementation. | 379 // content::DownloadItem::Observer implementation. |
380 virtual void OnDownloadDestroyed(content::DownloadItem* download) OVERRIDE { | 380 virtual void OnDownloadDestroyed(content::DownloadItem* download) OVERRIDE { |
381 Cancel(); | 381 Cancel(); |
382 DCHECK(item_ == NULL); | 382 DCHECK(item_ == NULL); |
383 } | 383 } |
384 | 384 |
385 // From the net::URLFetcherDelegate interface. | 385 // From the net::URLFetcherDelegate interface. |
386 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE { | 386 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE { |
387 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 387 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
388 DCHECK_EQ(source, fetcher_.get()); | 388 DCHECK_EQ(source, fetcher_.get()); |
389 VLOG(2) << "Received a response for URL: " | 389 VLOG(2) << "Received a response for URL: " |
390 << item_->GetUrlChain().back() << ": success=" | 390 << item_->GetUrlChain().back() << ": success=" |
391 << source->GetStatus().is_success() << " response_code=" | 391 << source->GetStatus().is_success() << " response_code=" |
392 << source->GetResponseCode(); | 392 << source->GetResponseCode(); |
393 if (source->GetStatus().is_success()) { | 393 if (source->GetStatus().is_success()) { |
394 UMA_HISTOGRAM_SPARSE_SLOWLY( | 394 UMA_HISTOGRAM_SPARSE_SLOWLY( |
395 "SBClientDownload.DownloadRequestResponseCode", | 395 "SBClientDownload.DownloadRequestResponseCode", |
396 source->GetResponseCode()); | 396 source->GetResponseCode()); |
397 } | 397 } |
398 UMA_HISTOGRAM_SPARSE_SLOWLY( | 398 UMA_HISTOGRAM_SPARSE_SLOWLY( |
399 "SBClientDownload.DownloadRequestNetError", | 399 "SBClientDownload.DownloadRequestNetError", |
400 -source->GetStatus().error()); | 400 -source->GetStatus().error()); |
401 DownloadCheckResultReason reason = REASON_SERVER_PING_FAILED; | 401 DownloadCheckResultReason reason = REASON_SERVER_PING_FAILED; |
402 DownloadCheckResult result = SAFE; | 402 DownloadCheckResult result = UNKNOWN; |
403 if (source->GetStatus().is_success() && | 403 if (source->GetStatus().is_success() && |
404 net::HTTP_OK == source->GetResponseCode()) { | 404 net::HTTP_OK == source->GetResponseCode()) { |
405 ClientDownloadResponse response; | 405 ClientDownloadResponse response; |
406 std::string data; | 406 std::string data; |
407 bool got_data = source->GetResponseAsString(&data); | 407 bool got_data = source->GetResponseAsString(&data); |
408 DCHECK(got_data); | 408 DCHECK(got_data); |
409 if (!response.ParseFromString(data)) { | 409 if (!response.ParseFromString(data)) { |
410 reason = REASON_INVALID_RESPONSE_PROTO; | 410 reason = REASON_INVALID_RESPONSE_PROTO; |
| 411 result = UNKNOWN; |
411 } else if (response.verdict() == ClientDownloadResponse::SAFE) { | 412 } else if (response.verdict() == ClientDownloadResponse::SAFE) { |
412 reason = REASON_DOWNLOAD_SAFE; | 413 reason = REASON_DOWNLOAD_SAFE; |
| 414 result = SAFE; |
413 } else if (service_ && !service_->IsSupportedDownload( | 415 } else if (service_ && !service_->IsSupportedDownload( |
414 *item_, item_->GetTargetFilePath())) { | 416 *item_, item_->GetTargetFilePath())) { |
415 // The client of the download protection service assumes that we don't | 417 // The client of the download protection service assumes that we don't |
416 // support this download so we cannot return any other verdict than | 418 // support this download so we cannot return any other verdict than |
417 // SAFE even if the server says it's dangerous to download this file. | 419 // UNKNOWN even if the server says it's dangerous to download this file. |
418 // Note: if service_ is NULL we already cancelled the request and | 420 // Note: if service_ is NULL we already cancelled the request and |
419 // returned SAFE. | 421 // returned UNKNOWN. |
420 reason = REASON_DOWNLOAD_NOT_SUPPORTED; | 422 reason = REASON_DOWNLOAD_NOT_SUPPORTED; |
| 423 result = UNKNOWN; |
421 } else if (response.verdict() == ClientDownloadResponse::DANGEROUS) { | 424 } else if (response.verdict() == ClientDownloadResponse::DANGEROUS) { |
422 reason = REASON_DOWNLOAD_DANGEROUS; | 425 reason = REASON_DOWNLOAD_DANGEROUS; |
423 result = DANGEROUS; | 426 result = DANGEROUS; |
424 } else if (response.verdict() == ClientDownloadResponse::UNCOMMON) { | 427 } else if (response.verdict() == ClientDownloadResponse::UNCOMMON) { |
425 reason = REASON_DOWNLOAD_UNCOMMON; | 428 reason = REASON_DOWNLOAD_UNCOMMON; |
426 result = UNCOMMON; | 429 result = UNCOMMON; |
427 } else if (response.verdict() == ClientDownloadResponse::DANGEROUS_HOST) { | 430 } else if (response.verdict() == ClientDownloadResponse::DANGEROUS_HOST) { |
428 reason = REASON_DOWNLOAD_DANGEROUS_HOST; | 431 reason = REASON_DOWNLOAD_DANGEROUS_HOST; |
429 result = DANGEROUS_HOST; | 432 result = DANGEROUS_HOST; |
430 } else if ( | 433 } else if ( |
431 response.verdict() == ClientDownloadResponse::POTENTIALLY_UNWANTED) { | 434 response.verdict() == ClientDownloadResponse::POTENTIALLY_UNWANTED) { |
432 reason = REASON_DOWNLOAD_POTENTIALLY_UNWANTED; | 435 reason = REASON_DOWNLOAD_POTENTIALLY_UNWANTED; |
433 result = POTENTIALLY_UNWANTED; | 436 result = POTENTIALLY_UNWANTED; |
434 } else { | 437 } else { |
435 LOG(DFATAL) << "Unknown download response verdict: " | 438 LOG(DFATAL) << "Unknown download response verdict: " |
436 << response.verdict(); | 439 << response.verdict(); |
437 reason = REASON_INVALID_RESPONSE_VERDICT; | 440 reason = REASON_INVALID_RESPONSE_VERDICT; |
| 441 result = UNKNOWN; |
438 } | 442 } |
439 DownloadFeedbackService::MaybeStorePingsForDownload( | 443 DownloadFeedbackService::MaybeStorePingsForDownload( |
440 result, item_, client_download_request_data_, data); | 444 result, item_, client_download_request_data_, data); |
441 } | 445 } |
442 // We don't need the fetcher anymore. | 446 // We don't need the fetcher anymore. |
443 fetcher_.reset(); | 447 fetcher_.reset(); |
444 UMA_HISTOGRAM_TIMES("SBClientDownload.DownloadRequestDuration", | 448 UMA_HISTOGRAM_TIMES("SBClientDownload.DownloadRequestDuration", |
445 base::TimeTicks::Now() - start_time_); | 449 base::TimeTicks::Now() - start_time_); |
446 UMA_HISTOGRAM_TIMES("SBClientDownload.DownloadRequestNetworkDuration", | 450 UMA_HISTOGRAM_TIMES("SBClientDownload.DownloadRequestNetworkDuration", |
447 base::TimeTicks::Now() - request_start_time_); | 451 base::TimeTicks::Now() - request_start_time_); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
559 VLOG(1) << "Zip analysis failed for " << item_->GetFullPath().value(); | 563 VLOG(1) << "Zip analysis failed for " << item_->GetFullPath().value(); |
560 } | 564 } |
561 UMA_HISTOGRAM_BOOLEAN("SBClientDownload.ZipFileHasExecutable", | 565 UMA_HISTOGRAM_BOOLEAN("SBClientDownload.ZipFileHasExecutable", |
562 zipped_executable_); | 566 zipped_executable_); |
563 UMA_HISTOGRAM_BOOLEAN("SBClientDownload.ZipFileHasArchiveButNoExecutable", | 567 UMA_HISTOGRAM_BOOLEAN("SBClientDownload.ZipFileHasArchiveButNoExecutable", |
564 results.has_archive && !zipped_executable_); | 568 results.has_archive && !zipped_executable_); |
565 UMA_HISTOGRAM_TIMES("SBClientDownload.ExtractZipFeaturesTime", | 569 UMA_HISTOGRAM_TIMES("SBClientDownload.ExtractZipFeaturesTime", |
566 base::TimeTicks::Now() - zip_analysis_start_time_); | 570 base::TimeTicks::Now() - zip_analysis_start_time_); |
567 | 571 |
568 if (!zipped_executable_) { | 572 if (!zipped_executable_) { |
569 PostFinishTask(SAFE, REASON_ARCHIVE_WITHOUT_BINARIES); | 573 PostFinishTask(UNKNOWN, REASON_ARCHIVE_WITHOUT_BINARIES); |
570 return; | 574 return; |
571 } | 575 } |
572 OnFileFeatureExtractionDone(); | 576 OnFileFeatureExtractionDone(); |
573 } | 577 } |
574 | 578 |
| 579 static void RecordCountOfSignedOrWhitelistedDownload() { |
| 580 UMA_HISTOGRAM_COUNTS("SBClientDownload.SignedOrWhitelistedDownload", 1); |
| 581 } |
| 582 |
575 void CheckWhitelists() { | 583 void CheckWhitelists() { |
576 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 584 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
577 DownloadCheckResultReason reason = REASON_MAX; | 585 |
578 if (!database_manager_.get()) { | 586 if (!database_manager_.get()) { |
579 reason = REASON_SB_DISABLED; | 587 PostFinishTask(UNKNOWN, REASON_SB_DISABLED); |
580 } else { | 588 return; |
581 const GURL& url = url_chain_.back(); | |
582 if (url.is_valid() && database_manager_->MatchDownloadWhitelistUrl(url)) { | |
583 VLOG(2) << url << " is on the download whitelist."; | |
584 reason = REASON_WHITELISTED_URL; | |
585 } | |
586 if (reason != REASON_MAX || signature_info_.trusted()) { | |
587 UMA_HISTOGRAM_COUNTS("SBClientDownload.SignedOrWhitelistedDownload", 1); | |
588 } | |
589 } | 589 } |
590 if (reason == REASON_MAX && signature_info_.trusted()) { | 590 |
| 591 const GURL& url = url_chain_.back(); |
| 592 if (url.is_valid() && database_manager_->MatchDownloadWhitelistUrl(url)) { |
| 593 VLOG(2) << url << " is on the download whitelist."; |
| 594 RecordCountOfSignedOrWhitelistedDownload(); |
| 595 PostFinishTask(SAFE, REASON_WHITELISTED_URL); |
| 596 return; |
| 597 } |
| 598 |
| 599 if (signature_info_.trusted()) { |
| 600 RecordCountOfSignedOrWhitelistedDownload(); |
591 for (int i = 0; i < signature_info_.certificate_chain_size(); ++i) { | 601 for (int i = 0; i < signature_info_.certificate_chain_size(); ++i) { |
592 if (CertificateChainIsWhitelisted( | 602 if (CertificateChainIsWhitelisted( |
593 signature_info_.certificate_chain(i))) { | 603 signature_info_.certificate_chain(i))) { |
594 reason = REASON_TRUSTED_EXECUTABLE; | 604 PostFinishTask(SAFE, REASON_TRUSTED_EXECUTABLE); |
595 break; | 605 return; |
596 } | 606 } |
597 } | 607 } |
598 } | 608 } |
599 if (reason != REASON_MAX) { | 609 |
600 PostFinishTask(SAFE, reason); | 610 if (!pingback_enabled_) { |
601 } else if (!pingback_enabled_) { | 611 PostFinishTask(UNKNOWN, REASON_PING_DISABLED); |
602 PostFinishTask(SAFE, REASON_PING_DISABLED); | 612 return; |
603 } else { | 613 } |
604 // Currently, the UI only works on Windows so we don't even bother | 614 |
605 // with pinging the server if we're not on Windows. TODO(noelutz): | 615 // Currently, the UI only works on Windows so we don't even bother with |
606 // change this code once the UI is done for Linux and Mac. | 616 // pinging the server if we're not on Windows. |
| 617 // TODO(noelutz): change this code once the UI is done for Linux and Mac. |
607 #if defined(OS_WIN) | 618 #if defined(OS_WIN) |
608 // The URLFetcher is owned by the UI thread, so post a message to | 619 // The URLFetcher is owned by the UI thread, so post a message to |
609 // start the pingback. | 620 // start the pingback. |
610 BrowserThread::PostTask( | 621 BrowserThread::PostTask( |
611 BrowserThread::UI, | 622 BrowserThread::UI, |
612 FROM_HERE, | 623 FROM_HERE, |
613 base::Bind(&CheckClientDownloadRequest::GetTabRedirects, this)); | 624 base::Bind(&CheckClientDownloadRequest::GetTabRedirects, this)); |
614 #else | 625 #else |
615 PostFinishTask(SAFE, REASON_OS_NOT_SUPPORTED); | 626 PostFinishTask(UNKNOWN, REASON_OS_NOT_SUPPORTED); |
616 #endif | 627 #endif |
617 } | |
618 } | 628 } |
619 | 629 |
620 void GetTabRedirects() { | 630 void GetTabRedirects() { |
621 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 631 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
622 if (!tab_url_.is_valid()) { | 632 if (!tab_url_.is_valid()) { |
623 SendRequest(); | 633 SendRequest(); |
624 return; | 634 return; |
625 } | 635 } |
626 | 636 |
627 Profile* profile = Profile::FromBrowserContext(item_->GetBrowserContext()); | 637 Profile* profile = Profile::FromBrowserContext(item_->GetBrowserContext()); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
702 } | 712 } |
703 } | 713 } |
704 | 714 |
705 request.set_user_initiated(item_->HasUserGesture()); | 715 request.set_user_initiated(item_->HasUserGesture()); |
706 request.set_file_basename( | 716 request.set_file_basename( |
707 item_->GetTargetFilePath().BaseName().AsUTF8Unsafe()); | 717 item_->GetTargetFilePath().BaseName().AsUTF8Unsafe()); |
708 request.set_download_type(type_); | 718 request.set_download_type(type_); |
709 request.mutable_signature()->CopyFrom(signature_info_); | 719 request.mutable_signature()->CopyFrom(signature_info_); |
710 request.mutable_image_headers()->CopyFrom(image_headers_); | 720 request.mutable_image_headers()->CopyFrom(image_headers_); |
711 if (!request.SerializeToString(&client_download_request_data_)) { | 721 if (!request.SerializeToString(&client_download_request_data_)) { |
712 FinishRequest(SAFE, REASON_INVALID_REQUEST_PROTO); | 722 FinishRequest(UNKNOWN, REASON_INVALID_REQUEST_PROTO); |
713 return; | 723 return; |
714 } | 724 } |
715 | 725 |
716 VLOG(2) << "Sending a request for URL: " | 726 VLOG(2) << "Sending a request for URL: " |
717 << item_->GetUrlChain().back(); | 727 << item_->GetUrlChain().back(); |
718 fetcher_.reset(net::URLFetcher::Create(0 /* ID used for testing */, | 728 fetcher_.reset(net::URLFetcher::Create(0 /* ID used for testing */, |
719 GetDownloadRequestUrl(), | 729 GetDownloadRequestUrl(), |
720 net::URLFetcher::POST, | 730 net::URLFetcher::POST, |
721 this)); | 731 this)); |
722 fetcher_->SetLoadFlags(net::LOAD_DISABLE_CACHE); | 732 fetcher_->SetLoadFlags(net::LOAD_DISABLE_CACHE); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
758 UMA_HISTOGRAM_ENUMERATION("SBClientDownload.DownloadRequestTimeoutStats", | 768 UMA_HISTOGRAM_ENUMERATION("SBClientDownload.DownloadRequestTimeoutStats", |
759 reason, | 769 reason, |
760 REASON_MAX); | 770 REASON_MAX); |
761 if (reason != REASON_REQUEST_CANCELED) { | 771 if (reason != REASON_REQUEST_CANCELED) { |
762 UMA_HISTOGRAM_TIMES("SBClientDownload.DownloadRequestTimeoutDuration", | 772 UMA_HISTOGRAM_TIMES("SBClientDownload.DownloadRequestTimeoutDuration", |
763 base::TimeTicks::Now() - timeout_start_time_); | 773 base::TimeTicks::Now() - timeout_start_time_); |
764 } | 774 } |
765 } | 775 } |
766 if (service_) { | 776 if (service_) { |
767 VLOG(2) << "SafeBrowsing download verdict for: " | 777 VLOG(2) << "SafeBrowsing download verdict for: " |
768 << item_->DebugString(true) << " verdict:" << reason; | 778 << item_->DebugString(true) << " verdict:" << reason |
| 779 << " result:" << result; |
769 UMA_HISTOGRAM_ENUMERATION("SBClientDownload.CheckDownloadStats", | 780 UMA_HISTOGRAM_ENUMERATION("SBClientDownload.CheckDownloadStats", |
770 reason, | 781 reason, |
771 REASON_MAX); | 782 REASON_MAX); |
772 callback_.Run(result); | 783 callback_.Run(result); |
773 item_->RemoveObserver(this); | 784 item_->RemoveObserver(this); |
774 item_ = NULL; | 785 item_ = NULL; |
775 DownloadProtectionService* service = service_; | 786 DownloadProtectionService* service = service_; |
776 service_ = NULL; | 787 service_ = NULL; |
777 service->RequestFinished(this); | 788 service->RequestFinished(this); |
778 // DownloadProtectionService::RequestFinished will decrement our refcount, | 789 // DownloadProtectionService::RequestFinished will decrement our refcount, |
779 // so we may be deleted now. | 790 // so we may be deleted now. |
780 } else { | 791 } else { |
781 callback_.Run(SAFE); | 792 callback_.Run(UNKNOWN); |
782 } | 793 } |
783 } | 794 } |
784 | 795 |
785 bool CertificateChainIsWhitelisted( | 796 bool CertificateChainIsWhitelisted( |
786 const ClientDownloadRequest_CertificateChain& chain) { | 797 const ClientDownloadRequest_CertificateChain& chain) { |
787 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 798 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
788 if (chain.element_size() < 2) { | 799 if (chain.element_size() < 2) { |
789 // We need to have both a signing certificate and its issuer certificate | 800 // We need to have both a signing certificate and its issuer certificate |
790 // present to construct a whitelist entry. | 801 // present to construct a whitelist entry. |
791 return false; | 802 return false; |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1050 GURL DownloadProtectionService::GetDownloadRequestUrl() { | 1061 GURL DownloadProtectionService::GetDownloadRequestUrl() { |
1051 GURL url(kDownloadRequestUrl); | 1062 GURL url(kDownloadRequestUrl); |
1052 std::string api_key = google_apis::GetAPIKey(); | 1063 std::string api_key = google_apis::GetAPIKey(); |
1053 if (!api_key.empty()) | 1064 if (!api_key.empty()) |
1054 url = url.Resolve("?key=" + net::EscapeQueryParamValue(api_key, true)); | 1065 url = url.Resolve("?key=" + net::EscapeQueryParamValue(api_key, true)); |
1055 | 1066 |
1056 return url; | 1067 return url; |
1057 } | 1068 } |
1058 | 1069 |
1059 } // namespace safe_browsing | 1070 } // namespace safe_browsing |
OLD | NEW |