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