| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/download/download_target_determiner.h" | 5 #include "chrome/browser/download/download_target_determiner.h" |
| 6 | 6 |
| 7 #include "base/location.h" | 7 #include "base/location.h" |
| 8 #include "base/rand_util.h" | 8 #include "base/rand_util.h" |
| 9 #include "base/single_thread_task_runner.h" | 9 #include "base/single_thread_task_runner.h" |
| 10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
| 11 #include "base/threading/thread_task_runner_handle.h" | 11 #include "base/threading/thread_task_runner_handle.h" |
| 12 #include "base/time/time.h" | 12 #include "base/time/time.h" |
| 13 #include "build/build_config.h" | 13 #include "build/build_config.h" |
| 14 #include "chrome/browser/download/chrome_download_manager_delegate.h" | 14 #include "chrome/browser/download/chrome_download_manager_delegate.h" |
| 15 #include "chrome/browser/download/download_crx_util.h" | 15 #include "chrome/browser/download/download_crx_util.h" |
| 16 #include "chrome/browser/download/download_extensions.h" | |
| 17 #include "chrome/browser/download/download_prefs.h" | 16 #include "chrome/browser/download/download_prefs.h" |
| 18 #include "chrome/browser/history/history_service_factory.h" | 17 #include "chrome/browser/history/history_service_factory.h" |
| 19 #include "chrome/browser/profiles/profile.h" | 18 #include "chrome/browser/profiles/profile.h" |
| 20 #include "chrome/common/pref_names.h" | 19 #include "chrome/common/pref_names.h" |
| 20 #include "chrome/common/safe_browsing/file_type_policies.h" |
| 21 #include "chrome/grit/generated_resources.h" | 21 #include "chrome/grit/generated_resources.h" |
| 22 #include "components/history/core/browser/history_service.h" | 22 #include "components/history/core/browser/history_service.h" |
| 23 #include "components/mime_util/mime_util.h" | 23 #include "components/mime_util/mime_util.h" |
| 24 #include "components/prefs/pref_service.h" | 24 #include "components/prefs/pref_service.h" |
| 25 #include "content/public/browser/browser_context.h" | 25 #include "content/public/browser/browser_context.h" |
| 26 #include "content/public/browser/browser_thread.h" | 26 #include "content/public/browser/browser_thread.h" |
| 27 #include "content/public/browser/download_interrupt_reasons.h" | 27 #include "content/public/browser/download_interrupt_reasons.h" |
| 28 #include "extensions/common/constants.h" | 28 #include "extensions/common/constants.h" |
| 29 #include "net/base/filename_util.h" | 29 #include "net/base/filename_util.h" |
| 30 #include "ui/base/l10n/l10n_util.h" | 30 #include "ui/base/l10n/l10n_util.h" |
| 31 | 31 |
| 32 #if defined(ENABLE_EXTENSIONS) | 32 #if defined(ENABLE_EXTENSIONS) |
| 33 #include "chrome/browser/extensions/webstore_installer.h" | 33 #include "chrome/browser/extensions/webstore_installer.h" |
| 34 #include "extensions/common/feature_switch.h" | 34 #include "extensions/common/feature_switch.h" |
| 35 #endif | 35 #endif |
| 36 | 36 |
| 37 #if defined(ENABLE_PLUGINS) | 37 #if defined(ENABLE_PLUGINS) |
| 38 #include "chrome/browser/plugins/plugin_prefs.h" | 38 #include "chrome/browser/plugins/plugin_prefs.h" |
| 39 #include "content/public/browser/plugin_service.h" | 39 #include "content/public/browser/plugin_service.h" |
| 40 #include "content/public/common/webplugininfo.h" | 40 #include "content/public/common/webplugininfo.h" |
| 41 #endif | 41 #endif |
| 42 | 42 |
| 43 #if defined(OS_WIN) | 43 #if defined(OS_WIN) |
| 44 #include "chrome/browser/ui/pdf/adobe_reader_info_win.h" | 44 #include "chrome/browser/ui/pdf/adobe_reader_info_win.h" |
| 45 #endif | 45 #endif |
| 46 | 46 |
| 47 using content::BrowserThread; | 47 using content::BrowserThread; |
| 48 using content::DownloadItem; | 48 using content::DownloadItem; |
| 49 using safe_browsing::DownloadFileType; |
| 49 | 50 |
| 50 namespace { | 51 namespace { |
| 51 | 52 |
| 52 const base::FilePath::CharType kCrdownloadSuffix[] = | 53 const base::FilePath::CharType kCrdownloadSuffix[] = |
| 53 FILE_PATH_LITERAL(".crdownload"); | 54 FILE_PATH_LITERAL(".crdownload"); |
| 54 | 55 |
| 55 // Condenses the results from HistoryService::GetVisibleVisitCountToHost() to a | 56 // Condenses the results from HistoryService::GetVisibleVisitCountToHost() to a |
| 56 // single bool. A host is considered visited before if prior visible visits were | 57 // single bool. A host is considered visited before if prior visible visits were |
| 57 // found in history and the first such visit was earlier than the most recent | 58 // found in history and the first such visit was earlier than the most recent |
| 58 // midnight. | 59 // midnight. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 69 #if defined(OS_WIN) | 70 #if defined(OS_WIN) |
| 70 // Keeps track of whether Adobe Reader is up to date. | 71 // Keeps track of whether Adobe Reader is up to date. |
| 71 bool g_is_adobe_reader_up_to_date_ = false; | 72 bool g_is_adobe_reader_up_to_date_ = false; |
| 72 #endif | 73 #endif |
| 73 | 74 |
| 74 } // namespace | 75 } // namespace |
| 75 | 76 |
| 76 DownloadTargetInfo::DownloadTargetInfo() | 77 DownloadTargetInfo::DownloadTargetInfo() |
| 77 : target_disposition(DownloadItem::TARGET_DISPOSITION_OVERWRITE), | 78 : target_disposition(DownloadItem::TARGET_DISPOSITION_OVERWRITE), |
| 78 danger_type(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS), | 79 danger_type(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS), |
| 79 danger_level(download_util::NOT_DANGEROUS), | 80 danger_level(DownloadFileType::NOT_DANGEROUS), |
| 80 is_filetype_handled_safely(false) {} | 81 is_filetype_handled_safely(false) {} |
| 81 | 82 |
| 82 DownloadTargetInfo::~DownloadTargetInfo() {} | 83 DownloadTargetInfo::~DownloadTargetInfo() {} |
| 83 | 84 |
| 84 DownloadTargetDeterminerDelegate::~DownloadTargetDeterminerDelegate() { | 85 DownloadTargetDeterminerDelegate::~DownloadTargetDeterminerDelegate() { |
| 85 } | 86 } |
| 86 | 87 |
| 87 DownloadTargetDeterminer::DownloadTargetDeterminer( | 88 DownloadTargetDeterminer::DownloadTargetDeterminer( |
| 88 DownloadItem* download, | 89 DownloadItem* download, |
| 89 const base::FilePath& initial_virtual_path, | 90 const base::FilePath& initial_virtual_path, |
| 90 DownloadPrefs* download_prefs, | 91 DownloadPrefs* download_prefs, |
| 91 DownloadTargetDeterminerDelegate* delegate, | 92 DownloadTargetDeterminerDelegate* delegate, |
| 92 const CompletionCallback& callback) | 93 const CompletionCallback& callback) |
| 93 : next_state_(STATE_GENERATE_TARGET_PATH), | 94 : next_state_(STATE_GENERATE_TARGET_PATH), |
| 94 should_prompt_(false), | 95 should_prompt_(false), |
| 95 should_notify_extensions_(false), | 96 should_notify_extensions_(false), |
| 96 create_target_directory_(false), | 97 create_target_directory_(false), |
| 97 conflict_action_(DownloadPathReservationTracker::OVERWRITE), | 98 conflict_action_(DownloadPathReservationTracker::OVERWRITE), |
| 98 danger_type_(download->GetDangerType()), | 99 danger_type_(download->GetDangerType()), |
| 99 danger_level_(download_util::NOT_DANGEROUS), | 100 danger_level_(DownloadFileType::NOT_DANGEROUS), |
| 100 virtual_path_(initial_virtual_path), | 101 virtual_path_(initial_virtual_path), |
| 101 is_filetype_handled_safely_(false), | 102 is_filetype_handled_safely_(false), |
| 102 download_(download), | 103 download_(download), |
| 103 is_resumption_(download_->GetLastReason() != | 104 is_resumption_(download_->GetLastReason() != |
| 104 content::DOWNLOAD_INTERRUPT_REASON_NONE && | 105 content::DOWNLOAD_INTERRUPT_REASON_NONE && |
| 105 !initial_virtual_path.empty()), | 106 !initial_virtual_path.empty()), |
| 106 download_prefs_(download_prefs), | 107 download_prefs_(download_prefs), |
| 107 delegate_(delegate), | 108 delegate_(delegate), |
| 108 completion_callback_(callback), | 109 completion_callback_(callback), |
| 109 weak_ptr_factory_(this) { | 110 weak_ptr_factory_(this) { |
| (...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 604 // Checking if there are prior visits to the referrer is only necessary if the | 605 // Checking if there are prior visits to the referrer is only necessary if the |
| 605 // danger level of the download depends on the file type. | 606 // danger level of the download depends on the file type. |
| 606 if (danger_type_ != content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS && | 607 if (danger_type_ != content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS && |
| 607 danger_type_ != content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT) | 608 danger_type_ != content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT) |
| 608 return CONTINUE; | 609 return CONTINUE; |
| 609 | 610 |
| 610 // First determine the danger level assuming that the user doesn't have any | 611 // First determine the danger level assuming that the user doesn't have any |
| 611 // prior visits to the referrer recoreded in history. The resulting danger | 612 // prior visits to the referrer recoreded in history. The resulting danger |
| 612 // level would be ALLOW_ON_USER_GESTURE if the level depends on the visit | 613 // level would be ALLOW_ON_USER_GESTURE if the level depends on the visit |
| 613 // history. In the latter case, we can query the history DB to determine if | 614 // history. In the latter case, we can query the history DB to determine if |
| 614 // there were prior reqeusts and determine the danger level again once the | 615 // there were prior requests and determine the danger level again once the |
| 615 // result is available. | 616 // result is available. |
| 616 danger_level_ = GetDangerLevel(NO_VISITS_TO_REFERRER); | 617 danger_level_ = GetDangerLevel(NO_VISITS_TO_REFERRER); |
| 617 | 618 |
| 618 if (danger_level_ == download_util::NOT_DANGEROUS) | 619 if (danger_level_ == DownloadFileType::NOT_DANGEROUS) |
| 619 return CONTINUE; | 620 return CONTINUE; |
| 620 | 621 |
| 621 if (danger_level_ == download_util::ALLOW_ON_USER_GESTURE) { | 622 if (danger_level_ == DownloadFileType::ALLOW_ON_USER_GESTURE) { |
| 622 // HistoryServiceFactory redirects incognito profiles to on-record profiles. | 623 // HistoryServiceFactory redirects incognito profiles to on-record profiles. |
| 623 // There's no history for on-record profiles in unit_tests. | 624 // There's no history for on-record profiles in unit_tests. |
| 624 history::HistoryService* history_service = | 625 history::HistoryService* history_service = |
| 625 HistoryServiceFactory::GetForProfile( | 626 HistoryServiceFactory::GetForProfile( |
| 626 GetProfile(), ServiceAccessType::EXPLICIT_ACCESS); | 627 GetProfile(), ServiceAccessType::EXPLICIT_ACCESS); |
| 627 | 628 |
| 628 if (history_service && download_->GetReferrerUrl().is_valid()) { | 629 if (history_service && download_->GetReferrerUrl().is_valid()) { |
| 629 history_service->GetVisibleVisitCountToHost( | 630 history_service->GetVisibleVisitCountToHost( |
| 630 download_->GetReferrerUrl(), | 631 download_->GetReferrerUrl(), |
| 631 base::Bind( | 632 base::Bind( |
| (...skipping 13 matching lines...) Expand all Loading... |
| 645 danger_type_ = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE; | 646 danger_type_ = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE; |
| 646 return CONTINUE; | 647 return CONTINUE; |
| 647 } | 648 } |
| 648 | 649 |
| 649 void DownloadTargetDeterminer::CheckVisitedReferrerBeforeDone( | 650 void DownloadTargetDeterminer::CheckVisitedReferrerBeforeDone( |
| 650 bool visited_referrer_before) { | 651 bool visited_referrer_before) { |
| 651 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 652 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 652 DCHECK_EQ(STATE_DETERMINE_INTERMEDIATE_PATH, next_state_); | 653 DCHECK_EQ(STATE_DETERMINE_INTERMEDIATE_PATH, next_state_); |
| 653 danger_level_ = GetDangerLevel( | 654 danger_level_ = GetDangerLevel( |
| 654 visited_referrer_before ? VISITED_REFERRER : NO_VISITS_TO_REFERRER); | 655 visited_referrer_before ? VISITED_REFERRER : NO_VISITS_TO_REFERRER); |
| 655 if (danger_level_ != download_util::NOT_DANGEROUS && | 656 if (danger_level_ != DownloadFileType::NOT_DANGEROUS && |
| 656 danger_type_ == content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) | 657 danger_type_ == content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) |
| 657 danger_type_ = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE; | 658 danger_type_ = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE; |
| 658 DoLoop(); | 659 DoLoop(); |
| 659 } | 660 } |
| 660 | 661 |
| 661 DownloadTargetDeterminer::Result | 662 DownloadTargetDeterminer::Result |
| 662 DownloadTargetDeterminer::DoDetermineIntermediatePath() { | 663 DownloadTargetDeterminer::DoDetermineIntermediatePath() { |
| 663 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 664 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 664 DCHECK(!virtual_path_.empty()); | 665 DCHECK(!virtual_path_.empty()); |
| 665 DCHECK(!local_path_.empty()); | 666 DCHECK(!local_path_.empty()); |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 833 // files), or if an extension signals that the user be prompted on a filename | 834 // files), or if an extension signals that the user be prompted on a filename |
| 834 // conflict. | 835 // conflict. |
| 835 return false; | 836 return false; |
| 836 } | 837 } |
| 837 | 838 |
| 838 bool DownloadTargetDeterminer::HasPromptedForPath() const { | 839 bool DownloadTargetDeterminer::HasPromptedForPath() const { |
| 839 return (is_resumption_ && download_->GetTargetDisposition() == | 840 return (is_resumption_ && download_->GetTargetDisposition() == |
| 840 DownloadItem::TARGET_DISPOSITION_PROMPT); | 841 DownloadItem::TARGET_DISPOSITION_PROMPT); |
| 841 } | 842 } |
| 842 | 843 |
| 843 download_util::DownloadDangerLevel DownloadTargetDeterminer::GetDangerLevel( | 844 DownloadFileType::DangerLevel DownloadTargetDeterminer::GetDangerLevel( |
| 844 PriorVisitsToReferrer visits) const { | 845 PriorVisitsToReferrer visits) const { |
| 845 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 846 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 846 | 847 |
| 847 // If the user has has been prompted or will be, assume that the user has | 848 // If the user has has been prompted or will be, assume that the user has |
| 848 // approved the download. A programmatic download is considered safe unless it | 849 // approved the download. A programmatic download is considered safe unless it |
| 849 // contains malware. | 850 // contains malware. |
| 850 if (HasPromptedForPath() || should_prompt_ || | 851 if (HasPromptedForPath() || should_prompt_ || |
| 851 !download_->GetForcedFilePath().empty()) | 852 !download_->GetForcedFilePath().empty()) |
| 852 return download_util::NOT_DANGEROUS; | 853 return DownloadFileType::NOT_DANGEROUS; |
| 853 | 854 |
| 854 const bool is_extension_download = | 855 const bool is_extension_download = |
| 855 download_crx_util::IsExtensionDownload(*download_); | 856 download_crx_util::IsExtensionDownload(*download_); |
| 856 | 857 |
| 857 // User-initiated extension downloads from pref-whitelisted sources are not | 858 // User-initiated extension downloads from pref-whitelisted sources are not |
| 858 // considered dangerous. | 859 // considered dangerous. |
| 859 if (download_->HasUserGesture() && | 860 if (download_->HasUserGesture() && |
| 860 is_extension_download && | 861 is_extension_download && |
| 861 download_crx_util::OffStoreInstallAllowedByPrefs( | 862 download_crx_util::OffStoreInstallAllowedByPrefs( |
| 862 GetProfile(), *download_)) { | 863 GetProfile(), *download_)) { |
| 863 return download_util::NOT_DANGEROUS; | 864 return DownloadFileType::NOT_DANGEROUS; |
| 864 } | 865 } |
| 865 | 866 |
| 866 #if defined(ENABLE_EXTENSIONS) | 867 #if defined(ENABLE_EXTENSIONS) |
| 867 // Extensions that are not from the gallery are considered dangerous. | 868 // Extensions that are not from the gallery are considered dangerous. |
| 868 // When off-store install is disabled we skip this, since in this case, we | 869 // When off-store install is disabled we skip this, since in this case, we |
| 869 // will not offer to install the extension. | 870 // will not offer to install the extension. |
| 870 if (extensions::FeatureSwitch::easy_off_store_install()->IsEnabled() && | 871 if (extensions::FeatureSwitch::easy_off_store_install()->IsEnabled() && |
| 871 is_extension_download && | 872 is_extension_download && |
| 872 !extensions::WebstoreInstaller::GetAssociatedApproval(*download_)) { | 873 !extensions::WebstoreInstaller::GetAssociatedApproval(*download_)) { |
| 873 return download_util::ALLOW_ON_USER_GESTURE; | 874 return DownloadFileType::ALLOW_ON_USER_GESTURE; |
| 874 } | 875 } |
| 875 #endif | 876 #endif |
| 876 | 877 |
| 877 // Anything the user has marked auto-open is OK if it's user-initiated. | 878 // Anything the user has marked auto-open is OK if it's user-initiated. |
| 878 if (download_prefs_->IsAutoOpenEnabledBasedOnExtension(virtual_path_) && | 879 if (download_prefs_->IsAutoOpenEnabledBasedOnExtension(virtual_path_) && |
| 879 download_->HasUserGesture()) | 880 download_->HasUserGesture()) |
| 880 return download_util::NOT_DANGEROUS; | 881 return DownloadFileType::NOT_DANGEROUS; |
| 881 | 882 |
| 882 download_util::DownloadDangerLevel danger_level = | 883 DownloadFileType::DangerLevel danger_level = |
| 883 download_util::GetFileDangerLevel(virtual_path_.BaseName()); | 884 safe_browsing::FileTypePolicies::GetInstance()->GetFileDangerLevel( |
| 885 virtual_path_.BaseName()); |
| 884 | 886 |
| 885 // If the danger level is ALLOW_ON_USER_GESTURE and we have a user gesture AND | 887 // If the danger level is ALLOW_ON_USER_GESTURE and we have a user gesture AND |
| 886 // there was a recorded visit to the referrer prior to today, then we are | 888 // there was a recorded visit to the referrer prior to today, then we are |
| 887 // going to downgrade the danger_level to NOT_DANGEROUS. This prevents | 889 // going to downgrade the danger_level to NOT_DANGEROUS. This prevents |
| 888 // spurious prompting for moderately dangerous files that are downloaded from | 890 // spurious prompting for moderately dangerous files that are downloaded from |
| 889 // familiar sites. | 891 // familiar sites. |
| 890 if (danger_level == download_util::ALLOW_ON_USER_GESTURE && | 892 if (danger_level == DownloadFileType::ALLOW_ON_USER_GESTURE && |
| 891 (download_->GetTransitionType() == ui::PAGE_TRANSITION_FROM_ADDRESS_BAR || | 893 (download_->GetTransitionType() == ui::PAGE_TRANSITION_FROM_ADDRESS_BAR || |
| 892 (download_->HasUserGesture() && visits == VISITED_REFERRER))) | 894 (download_->HasUserGesture() && visits == VISITED_REFERRER))) |
| 893 return download_util::NOT_DANGEROUS; | 895 return DownloadFileType::NOT_DANGEROUS; |
| 894 return danger_level; | 896 return danger_level; |
| 895 } | 897 } |
| 896 | 898 |
| 897 void DownloadTargetDeterminer::OnDownloadDestroyed( | 899 void DownloadTargetDeterminer::OnDownloadDestroyed( |
| 898 DownloadItem* download) { | 900 DownloadItem* download) { |
| 899 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 901 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 900 DCHECK_EQ(download_, download); | 902 DCHECK_EQ(download_, download); |
| 901 CancelOnFailureAndDeleteSelf(); | 903 CancelOnFailureAndDeleteSelf(); |
| 902 } | 904 } |
| 903 | 905 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 919 const base::FilePath& suggested_path) { | 921 const base::FilePath& suggested_path) { |
| 920 return base::FilePath(suggested_path.value() + kCrdownloadSuffix); | 922 return base::FilePath(suggested_path.value() + kCrdownloadSuffix); |
| 921 } | 923 } |
| 922 | 924 |
| 923 #if defined(OS_WIN) | 925 #if defined(OS_WIN) |
| 924 // static | 926 // static |
| 925 bool DownloadTargetDeterminer::IsAdobeReaderUpToDate() { | 927 bool DownloadTargetDeterminer::IsAdobeReaderUpToDate() { |
| 926 return g_is_adobe_reader_up_to_date_; | 928 return g_is_adobe_reader_up_to_date_; |
| 927 } | 929 } |
| 928 #endif | 930 #endif |
| OLD | NEW |