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 3 // found in the LICENSE file. 4 // 5 // Helper class which handles communication with the SafeBrowsing servers for 6 // improved binary download protection. 7 8 #ifndef CHROME_BROWSER_SAFE_BROWSING_DOWNLOAD_PROTECTION_SERVICE_H_ 9 #define CHROME_BROWSER_SAFE_BROWSING_DOWNLOAD_PROTECTION_SERVICE_H_ 10 11 #include <set> 12 #include <string> 13 #include <vector> 14 15 #include "base/basictypes.h" 16 #include "base/callback.h" 17 #include "base/files/file_path.h" 18 #include "base/gtest_prod_util.h" 19 #include "base/memory/ref_counted.h" 20 #include "chrome/browser/safe_browsing/database_manager.h" 21 #include "chrome/browser/safe_browsing/ui_manager.h" 22 #include "url/gurl.h" 23 24 25 namespace content { 26 class DownloadItem; 27 class PageNavigator; 28 } 29 30 namespace net { 31 class URLRequestContextGetter; 32 class X509Certificate; 33 } // namespace net 34 35 namespace safe_browsing { 36 class DownloadFeedbackService; 37 class BinaryFeatureExtractor; 38 39 // This class provides an asynchronous API to check whether a particular 40 // client download is malicious or not. 41 class DownloadProtectionService { 42 public: 43 enum DownloadCheckResult { 44 UNKNOWN, 45 SAFE, 46 DANGEROUS, 47 UNCOMMON, 48 DANGEROUS_HOST, 49 POTENTIALLY_UNWANTED 50 }; 51 52 // Callback type which is invoked once the download request is done. 53 typedef base::Callback<void(DownloadCheckResult)> CheckDownloadCallback; 54 55 // Creates a download service. The service is initially disabled. You need 56 // to call SetEnabled() to start it. |sb_service| owns this object; we 57 // keep a reference to |request_context_getter|. 58 DownloadProtectionService( 59 SafeBrowsingService* sb_service, 60 net::URLRequestContextGetter* request_context_getter); 61 62 virtual ~DownloadProtectionService(); 63 64 // Checks whether the given client download is likely to be malicious or not. 65 // The result is delivered asynchronously via the given callback. This 66 // method must be called on the UI thread, and the callback will also be 67 // invoked on the UI thread. This method must be called once the download 68 // is finished and written to disk. 69 virtual void CheckClientDownload(content::DownloadItem* item, 70 const CheckDownloadCallback& callback); 71 72 // Checks whether any of the URLs in the redirect chain of the 73 // download match the SafeBrowsing bad binary URL list. The result is 74 // delivered asynchronously via the given callback. This method must be 75 // called on the UI thread, and the callback will also be invoked on the UI 76 // thread. Pre-condition: !info.download_url_chain.empty(). 77 virtual void CheckDownloadUrl(const content::DownloadItem& item, 78 const CheckDownloadCallback& callback); 79 80 // Returns true iff the download specified by |info| should be scanned by 81 // CheckClientDownload() for malicious content. 82 virtual bool IsSupportedDownload(const content::DownloadItem& item, 83 const base::FilePath& target_path) const; 84 85 // Display more information to the user regarding the download specified by 86 // |info|. This method is invoked when the user requests more information 87 // about a download that was marked as malicious. 88 void ShowDetailsForDownload(const content::DownloadItem& item, 89 content::PageNavigator* navigator); 90 91 // Enables or disables the service. This is usually called by the 92 // SafeBrowsingService, which tracks whether any profile uses these services 93 // at all. Disabling causes any pending and future requests to have their 94 // callbacks called with "UNKNOWN" results. 95 void SetEnabled(bool enabled); 96 97 bool enabled() const { 98 return enabled_; 99 } 100 101 // Returns the timeout that is used by CheckClientDownload(). 102 int64 download_request_timeout_ms() const { 103 return download_request_timeout_ms_; 104 } 105 106 DownloadFeedbackService* feedback_service() { 107 return feedback_service_.get(); 108 } 109 110 protected: 111 // Enum to keep track why a particular download verdict was chosen. 112 // This is used to keep some stats around. 113 enum DownloadCheckResultReason { 114 REASON_INVALID_URL, 115 REASON_SB_DISABLED, 116 REASON_WHITELISTED_URL, 117 REASON_WHITELISTED_REFERRER, 118 REASON_INVALID_REQUEST_PROTO, 119 REASON_SERVER_PING_FAILED, 120 REASON_INVALID_RESPONSE_PROTO, 121 REASON_NOT_BINARY_FILE, 122 REASON_REQUEST_CANCELED, 123 REASON_DOWNLOAD_DANGEROUS, 124 REASON_DOWNLOAD_SAFE, 125 REASON_EMPTY_URL_CHAIN, 126 DEPRECATED_REASON_HTTPS_URL, 127 REASON_PING_DISABLED, 128 REASON_TRUSTED_EXECUTABLE, 129 REASON_OS_NOT_SUPPORTED, 130 REASON_DOWNLOAD_UNCOMMON, 131 REASON_DOWNLOAD_NOT_SUPPORTED, 132 REASON_INVALID_RESPONSE_VERDICT, 133 REASON_ARCHIVE_WITHOUT_BINARIES, 134 REASON_DOWNLOAD_DANGEROUS_HOST, 135 REASON_DOWNLOAD_POTENTIALLY_UNWANTED, 136 REASON_MAX // Always add new values before this one. 137 }; 138 139 private: 140 class CheckClientDownloadRequest; // Per-request state 141 friend class DownloadProtectionServiceTest; 142 FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest, 143 CheckClientDownloadWhitelistedUrl); 144 FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest, 145 CheckClientDownloadValidateRequest); 146 FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest, 147 CheckClientDownloadSuccess); 148 FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest, 149 CheckClientDownloadHTTPS); 150 FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest, 151 CheckClientDownloadZip); 152 FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest, 153 CheckClientDownloadFetchFailed); 154 FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest, 155 TestDownloadRequestTimeout); 156 FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest, 157 CheckClientCrxDownloadSuccess); 158 static const char kDownloadRequestUrl[]; 159 160 // Cancels all requests in |download_requests_|, and empties it, releasing 161 // the references to the requests. 162 void CancelPendingRequests(); 163 164 // Called by a CheckClientDownloadRequest instance when it finishes, to 165 // remove it from |download_requests_|. 166 void RequestFinished(CheckClientDownloadRequest* request); 167 168 // Given a certificate and its immediate issuer certificate, generates the 169 // list of strings that need to be checked against the download whitelist to 170 // determine whether the certificate is whitelisted. 171 static void GetCertificateWhitelistStrings( 172 const net::X509Certificate& certificate, 173 const net::X509Certificate& issuer, 174 std::vector<std::string>* whitelist_strings); 175 176 // Returns the URL that will be used for download requests. 177 static GURL GetDownloadRequestUrl(); 178 179 // These pointers may be NULL if SafeBrowsing is disabled. 180 scoped_refptr<SafeBrowsingUIManager> ui_manager_; 181 scoped_refptr<SafeBrowsingDatabaseManager> database_manager_; 182 183 // The context we use to issue network requests. 184 scoped_refptr<net::URLRequestContextGetter> request_context_getter_; 185 186 // Map of client download request to the corresponding callback that 187 // has to be invoked when the request is done. This map contains all 188 // pending server requests. 189 std::set<scoped_refptr<CheckClientDownloadRequest> > download_requests_; 190 191 // Keeps track of the state of the service. 192 bool enabled_; 193 194 // BinaryFeatureExtractor object, may be overridden for testing. 195 scoped_refptr<BinaryFeatureExtractor> binary_feature_extractor_; 196 197 int64 download_request_timeout_ms_; 198 199 scoped_ptr<DownloadFeedbackService> feedback_service_; 200 201 DISALLOW_COPY_AND_ASSIGN(DownloadProtectionService); 202 }; 203 } // namespace safe_browsing 204 205 #endif // CHROME_BROWSER_SAFE_BROWSING_DOWNLOAD_PROTECTION_SERVICE_H_ 206