15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper class which handles communication with the SafeBrowsing servers for 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// improved binary download protection. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_BROWSER_SAFE_BROWSING_DOWNLOAD_PROTECTION_SERVICE_H_ 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_SAFE_BROWSING_DOWNLOAD_PROTECTION_SERVICE_H_ 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/gtest_prod_util.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/safe_browsing/database_manager.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/safe_browsing/ui_manager.h" 22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DownloadItem; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PageNavigator; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class URLRequestContextGetter; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class X509Certificate; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace safe_browsing { 367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class DownloadFeedbackService; 37effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass BinaryFeatureExtractor; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class provides an asynchronous API to check whether a particular 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// client download is malicious or not. 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DownloadProtectionService { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum DownloadCheckResult { 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci UNKNOWN, 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SAFE, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DANGEROUS, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UNCOMMON, 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DANGEROUS_HOST, 49a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch POTENTIALLY_UNWANTED 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Callback type which is invoked once the download request is done. 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef base::Callback<void(DownloadCheckResult)> CheckDownloadCallback; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates a download service. The service is initially disabled. You need 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to call SetEnabled() to start it. |sb_service| owns this object; we 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // keep a reference to |request_context_getter|. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadProtectionService( 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SafeBrowsingService* sb_service, 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequestContextGetter* request_context_getter); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~DownloadProtectionService(); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Checks whether the given client download is likely to be malicious or not. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The result is delivered asynchronously via the given callback. This 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // method must be called on the UI thread, and the callback will also be 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // invoked on the UI thread. This method must be called once the download 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is finished and written to disk. 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void CheckClientDownload(content::DownloadItem* item, 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CheckDownloadCallback& callback); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Checks whether any of the URLs in the redirect chain of the 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // download match the SafeBrowsing bad binary URL list. The result is 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // delivered asynchronously via the given callback. This method must be 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // called on the UI thread, and the callback will also be invoked on the UI 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread. Pre-condition: !info.download_url_chain.empty(). 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void CheckDownloadUrl(const content::DownloadItem& item, 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CheckDownloadCallback& callback); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true iff the download specified by |info| should be scanned by 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CheckClientDownload() for malicious content. 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool IsSupportedDownload(const content::DownloadItem& item, 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& target_path) const; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Display more information to the user regarding the download specified by 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |info|. This method is invoked when the user requests more information 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // about a download that was marked as malicious. 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void ShowDetailsForDownload(const content::DownloadItem& item, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PageNavigator* navigator); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Enables or disables the service. This is usually called by the 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SafeBrowsingService, which tracks whether any profile uses these services 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // at all. Disabling causes any pending and future requests to have their 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // callbacks called with "UNKNOWN" results. 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetEnabled(bool enabled); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool enabled() const { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return enabled_; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the timeout that is used by CheckClientDownload(). 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 download_request_timeout_ms() const { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return download_request_timeout_ms_; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DownloadFeedbackService* feedback_service() { 1077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return feedback_service_.get(); 1087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 1097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Enum to keep track why a particular download verdict was chosen. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is used to keep some stats around. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum DownloadCheckResultReason { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) REASON_INVALID_URL, 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) REASON_SB_DISABLED, 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) REASON_WHITELISTED_URL, 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) REASON_WHITELISTED_REFERRER, 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) REASON_INVALID_REQUEST_PROTO, 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) REASON_SERVER_PING_FAILED, 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) REASON_INVALID_RESPONSE_PROTO, 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) REASON_NOT_BINARY_FILE, 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) REASON_REQUEST_CANCELED, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) REASON_DOWNLOAD_DANGEROUS, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) REASON_DOWNLOAD_SAFE, 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) REASON_EMPTY_URL_CHAIN, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEPRECATED_REASON_HTTPS_URL, 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) REASON_PING_DISABLED, 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) REASON_TRUSTED_EXECUTABLE, 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) REASON_OS_NOT_SUPPORTED, 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) REASON_DOWNLOAD_UNCOMMON, 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) REASON_DOWNLOAD_NOT_SUPPORTED, 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) REASON_INVALID_RESPONSE_VERDICT, 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) REASON_ARCHIVE_WITHOUT_BINARIES, 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) REASON_DOWNLOAD_DANGEROUS_HOST, 135a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch REASON_DOWNLOAD_POTENTIALLY_UNWANTED, 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) REASON_MAX // Always add new values before this one. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class CheckClientDownloadRequest; // Per-request state 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class DownloadProtectionServiceTest; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest, 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CheckClientDownloadWhitelistedUrl); 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest, 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckClientDownloadValidateRequest); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest, 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckClientDownloadSuccess); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckClientDownloadHTTPS); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest, 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckClientDownloadZip); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest, 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckClientDownloadFetchFailed); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest, 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestDownloadRequestTimeout); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest, 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckClientCrxDownloadSuccess); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kDownloadRequestUrl[]; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cancels all requests in |download_requests_|, and empties it, releasing 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the references to the requests. 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CancelPendingRequests(); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called by a CheckClientDownloadRequest instance when it finishes, to 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // remove it from |download_requests_|. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RequestFinished(CheckClientDownloadRequest* request); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Given a certificate and its immediate issuer certificate, generates the 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // list of strings that need to be checked against the download whitelist to 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // determine whether the certificate is whitelisted. 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void GetCertificateWhitelistStrings( 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::X509Certificate& certificate, 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::X509Certificate& issuer, 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string>* whitelist_strings); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the URL that will be used for download requests. 1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) static GURL GetDownloadRequestUrl(); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // These pointers may be NULL if SafeBrowsing is disabled. 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<SafeBrowsingUIManager> ui_manager_; 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<SafeBrowsingDatabaseManager> database_manager_; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The context we use to issue network requests. 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<net::URLRequestContextGetter> request_context_getter_; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Map of client download request to the corresponding callback that 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // has to be invoked when the request is done. This map contains all 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pending server requests. 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<scoped_refptr<CheckClientDownloadRequest> > download_requests_; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Keeps track of the state of the service. 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool enabled_; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 194effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // BinaryFeatureExtractor object, may be overridden for testing. 195effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch scoped_refptr<BinaryFeatureExtractor> binary_feature_extractor_; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 download_request_timeout_ms_; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<DownloadFeedbackService> feedback_service_; 2007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(DownloadProtectionService); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace safe_browsing 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // CHROME_BROWSER_SAFE_BROWSING_DOWNLOAD_PROTECTION_SERVICE_H_ 206